Instrument Neutral Distributed Interface INDI  1.9.2
dome.cpp

The dome driver snoops on the rain detector signal and watches whether rain is detected or not. If it is detector and the dome is closed, it performs no action, but it also prevents you from opening the dome due to rain. If the dome is open, it will automatically starts closing the shutter. In order snooping to work, both drivers must be started by the same indiserver (or chained INDI servers):

indiserver tutorial_dome tutorial_rain

The dome driver keeps a copy of RainL light property from the rain driver. This makes it easy to parse the property status once an update from the rain driver arrives in the dome driver. Alternatively, you can directly parse the XML root element in ISSnoopDevice(XMLEle *root) to extract the required data.

/*
INDI Developers Manual
Tutorial #5 - Snooping
Dome
Refer to README, which contains instruction on how to build this driver, and use it
with an INDI-compatible client.
*/
#include "dome.h"
#include <memory>
#include <cstring>
#include <unistd.h>
std::unique_ptr<Dome> dome(new Dome());
/**************************************************************************************
** Client is asking us to establish connection to the device
***************************************************************************************/
{
IDMessage(getDeviceName(), "Dome connected successfully!");
return true;
}
/**************************************************************************************
** Client is asking us to terminate connection to the device
***************************************************************************************/
{
IDMessage(getDeviceName(), "Dome disconnected successfully!");
return true;
}
/**************************************************************************************
** INDI is asking us for our default device name
***************************************************************************************/
const char *Dome::getDefaultName()
{
return "Dome";
}
/**************************************************************************************
** INDI is asking us to init our properties.
***************************************************************************************/
{
// Must init parent properties first!
IUFillSwitch(&ShutterS[0], "Open", "", ISS_ON);
IUFillSwitch(&ShutterS[1], "Close", "", ISS_OFF);
IUFillSwitchVector(&ShutterSP, ShutterS, 2, getDeviceName(), "Shutter Door", "", MAIN_CONTROL_TAB, IP_RW,
// We init here the property we wish to "snoop" from the target device
IUFillLight(&RainL[0], "Status", "", IPS_IDLE);
// Make sure to set the device name to "Rain Detector" since we are snooping on rain detector device.
IUFillLightVector(&RainLP, RainL, 1, "Rain Detector", "Rain Alert", "", MAIN_CONTROL_TAB, IPS_IDLE);
return true;
}
/********************************************************************************************
** INDI is asking us to update the properties because there is a change in CONNECTION status
** This fucntion is called whenever the device is connected or disconnected.
*********************************************************************************************/
{
// Call parent update properties first
if (isConnected())
{
defineProperty(&ShutterSP);
/* Let's listen for Rain Alert property in the device Rain */
IDSnoopDevice("Rain Detector", "Rain Alert");
}
else
// We're disconnected
deleteProperty(ShutterSP.name);
return true;
}
/********************************************************************************************
** Client is asking us to update a switch
*********************************************************************************************/
bool Dome::ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
{
if (dev != nullptr && strcmp(dev, getDeviceName()) == 0)
{
if (strcmp(name, ShutterSP.name) == 0)
{
IUUpdateSwitch(&ShutterSP, states, names, n);
ShutterSP.s = IPS_BUSY;
if (ShutterS[0].s == ISS_ON)
{
if (RainL[0].s == IPS_ALERT)
{
ShutterSP.s = IPS_ALERT;
ShutterS[0].s = ISS_OFF;
ShutterS[1].s = ISS_ON;
IDSetSwitch(&ShutterSP, "It is raining, cannot open Shutter.");
return true;
}
IDSetSwitch(&ShutterSP, "Shutter is opening.");
}
else
IDSetSwitch(&ShutterSP, "Shutter is closing.");
sleep(5);
ShutterSP.s = IPS_OK;
if (ShutterS[0].s == ISS_ON)
IDSetSwitch(&ShutterSP, "Shutter is open.");
else
IDSetSwitch(&ShutterSP, "Shutter is closed.");
return true;
}
}
return INDI::DefaultDevice::ISNewSwitch(dev, name, states, names, n);
}
/********************************************************************************************
** We received snooped property update from rain detector device
*********************************************************************************************/
{
IPState old_state = RainL[0].s;
/* If the "Rain Alert" property gets updated in the Rain device, we will receive a notification. We need to process the new values of Rain Alert and update the local version
of the property.*/
if (IUSnoopLight(root, &RainLP) == 0)
{
// If the dome is connected and rain is Alert */
if (RainL[0].s == IPS_ALERT)
{
// If dome is open, then close it */
if (ShutterS[0].s == ISS_ON)
closeShutter();
else
IDMessage(getDeviceName(), "Rain Alert Detected! Dome is already closed.");
}
else if (old_state == IPS_ALERT && RainL[0].s != IPS_ALERT)
IDMessage(getDeviceName(), "Rain threat passed. Opening the dome is now safe.");
return true;
}
return false;
}
/********************************************************************************************
** Close shutter
*********************************************************************************************/
void Dome::closeShutter()
{
ShutterSP.s = IPS_BUSY;
IDSetSwitch(&ShutterSP, "Rain Alert! Shutter is closing...");
sleep(5);
ShutterS[0].s = ISS_OFF;
ShutterS[1].s = ISS_ON;
ShutterSP.s = IPS_OK;
IDSetSwitch(&ShutterSP, "Shutter is closed.");
}
Dome
Definition: dome.h:30
dome.h
Construct a dome device that the user may operate to open or close the dome shutter door....
Dome::updateProperties
bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
Definition: dome.cpp:85
Dome::initProperties
bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
Definition: dome.cpp:63
IPState
IPState
Property state.
Definition: indiapi.h:158
IPS_OK
@ IPS_OK
Definition: indiapi.h:161
ISS_OFF
@ ISS_OFF
Definition: indiapi.h:150
IPS_ALERT
@ IPS_ALERT
Definition: indiapi.h:163
IUSnoopLight
int IUSnoopLight(XMLEle *root, ILightVectorProperty *lvp)
Update a snooped light vector property from the given XML root element.
Definition: indidriver.c:612
IDSnoopDevice
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...
Definition: indidriver.c:137
INDI::DefaultDevice::defineProperty
void defineProperty(INumberVectorProperty *property)
Definition: defaultdevice.cpp:997
MAIN_CONTROL_TAB
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
Definition: defaultdevice.cpp:34
Dome::ISNewSwitch
bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
Definition: dome.cpp:106
INDI::BaseDevice::getDeviceName
const char * getDeviceName() const
Definition: basedevice.cpp:799
IUFillLight
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.
Definition: indidriver.c:334
Dome::Disconnect
bool Disconnect() override
Disconnect from device.
Definition: dome.cpp:46
INDI::DefaultDevice::initProperties
virtual bool initProperties()
Initilize properties initial state and value. The child class must implement this function.
Definition: defaultdevice.cpp:917
Dome::getDefaultName
const char * getDefaultName() override
Definition: dome.cpp:55
Dome::Connect
bool Connect() override
Connect to the device. INDI::DefaultDevice implementation connects to appropriate connection interfac...
Definition: dome.cpp:37
IUFillSwitchVector
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.
Definition: indidriver.c:412
IPS_BUSY
@ IPS_BUSY
Definition: indiapi.h:162
ISR_1OFMANY
@ ISR_1OFMANY
Definition: indiapi.h:172
IPS_IDLE
@ IPS_IDLE
Definition: indiapi.h:160
dome
std::unique_ptr< Dome > dome(new Dome())
xml_ele_
Definition: lilxml.c:105
IDMessage
void IDMessage(const char *dev, const char *msg,...) ATTRIBUTE_FORMAT_PRINTF(2
Function Drivers call to send log messages to Clients.
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
Dome::ISSnoopDevice
bool ISSnoopDevice(XMLEle *root) override
Process a snoop event from INDI server. This function is called when a snooped property is updated in...
Definition: dome.cpp:151
_ISwitchVectorProperty::s
IPState s
Definition: indiapi.h:382
IP_RW
@ IP_RW
Definition: indiapi.h:185
ISState
ISState
Switch state.
Definition: indiapi.h:148
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
INDI::DefaultDevice::deleteProperty
virtual bool deleteProperty(const char *propertyName)
Delete a property and unregister it. It will also be deleted from all clients.
Definition: defaultdevice.cpp:965
IUFillLightVector
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.
Definition: indidriver.c:435
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.
IUFillSwitch
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.
Definition: indidriver.c:320
INDI::DefaultDevice::updateProperties
virtual bool updateProperties()
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
Definition: defaultdevice.cpp:890
_ISwitchVectorProperty::name
char name[MAXINDINAME]
Definition: indiapi.h:370
ISS_ON
@ ISS_ON
Definition: indiapi.h:151