11#ifndef app_indiUtils_hpp
12#define app_indiUtils_hpp
17#include "../../INDI/libcommon/IndiProperty.hpp"
18#include "../../INDI/libcommon/IndiElement.hpp"
27#define INDI_IDLE ( pcf::IndiProperty::Idle )
28#define INDI_OK ( pcf::IndiProperty::Ok )
29#define INDI_BUSY ( pcf::IndiProperty::Busy )
30#define INDI_ALERT ( pcf::IndiProperty::Alert )
38 const std::string &name,
39 const std::string &label =
""
42 prop.add( pcf::IndiElement( name,
"" ) );
47 prop[name].setLabel( label );
60 const std::string &name,
64 const std::string &format,
66 const std::string &label =
""
69 prop.add( pcf::IndiElement( name, 0 ) );
70 prop[name].setMin( min );
71 prop[name].setMax( max );
72 prop[name].setStep( step );
73 prop[name].setFormat( format );
78 prop[name].setLabel( label );
91template <
typename T,
class indiDriverT>
93 const std::string &el,
96 pcf::IndiProperty::PropertyStateType newState = pcf::IndiProperty::Ok )
106 std::stringstream ssValue;
107 ssValue.precision( 15 );
108 ssValue << std::boolalpha << newVal;
110 pcf::IndiProperty::PropertyStateType oldState = p.getState();
113 if( p[el].getValue() != ssValue.str() || oldState != newState )
116 p.setTimeStamp( pcf::TimeStamp() );
117 p.setState( newState );
121 catch( std::exception &e )
123 std::cerr <<
"Exception caught at " << __FILE__ <<
" " << __LINE__ <<
" ";
124 std::cerr <<
"from " << p.getName() <<
"." << el <<
": ";
125 std::cerr << e.what() <<
"\n";
129 std::cerr <<
"Exception caught at " << __FILE__ <<
" " << __LINE__ <<
" ";
130 std::cerr <<
"from " << p.getName() <<
"." << el <<
"\n";
139template <
typename T,
class indiDriverT>
141 const std::vector<std::string> &els,
142 const std::vector<T> &newVals,
144 pcf::IndiProperty::PropertyStateType newState = pcf::IndiProperty::Ok )
154 bool changed =
false;
155 pcf::IndiProperty::PropertyStateType oldState = p.getState();
157 if( oldState != newState )
160 for( n = 0; n < els.size() && changed !=
true; ++n )
163 std::stringstream ssValue;
164 ssValue.precision( 15 );
165 ssValue << std::boolalpha << newVals[n];
168 if( p[els[n]].getValue() != ssValue.str() )
175 for( n = 0; n < els.size(); ++n )
177 p[els[n]].set( newVals[n] );
179 p.setTimeStamp( pcf::TimeStamp() );
180 p.setState( newState );
184 catch( std::exception &e )
186 std::cerr <<
"Exception caught at " << __FILE__ <<
" " << __LINE__ <<
" ";
189 std::cerr <<
"from " << p.getName() <<
"." << els[n] <<
": ";
191 std::cerr << e.what() <<
"\n";
195 std::cerr <<
"Exception caught at " << __FILE__ <<
" " << __LINE__ <<
" ";
198 std::cerr <<
"from " << p.getName() <<
"." << els[n] <<
"\n";
210template <
typename T,
typename elVecT,
class indiDriverT>
213 const std::vector<T> &newVals,
215 pcf::IndiProperty::PropertyStateType newState = pcf::IndiProperty::Ok )
225 bool changed =
false;
226 pcf::IndiProperty::PropertyStateType oldState = p.getState();
228 if( oldState != newState )
231 for( n = 0; n < els.size() && changed !=
true; ++n )
234 std::stringstream ssValue;
235 ssValue.precision( 15 );
236 ssValue << std::boolalpha << newVals[n];
239 if( p[els[n]].getValue() != ssValue.str() )
246 for( n = 0; n < els.size(); ++n )
248 p[els[n]].set( newVals[n] );
250 p.setTimeStamp( pcf::TimeStamp() );
251 p.setState( newState );
255 catch( std::exception &e )
257 std::cerr <<
"Exception caught at " << __FILE__ <<
" " << __LINE__ <<
" ";
260 std::cerr <<
"from " << p.getName() <<
"." << els[n] <<
": ";
262 std::cerr << e.what() <<
"\n";
266 std::cerr <<
"Exception caught at " << __FILE__ <<
" " << __LINE__ <<
" ";
269 std::cerr <<
"from " << p.getName() <<
"." << els[n] <<
"\n";
283template <
typename T,
class indiDriverT>
285 const std::vector<const char *> &els,
286 const std::vector<T> &newVals,
288 pcf::IndiProperty::PropertyStateType newState = pcf::IndiProperty::Ok )
290 updatesIfChanged<T, std::vector<const char *>, indiDriverT>( p, els, newVals,
indiDriver, newState );
302template <
typename T,
class indiDriverT>
304 const std::vector<std::string> &els,
305 const std::vector<T> &newVals,
307 pcf::IndiProperty::PropertyStateType newState = pcf::IndiProperty::Ok )
309 updatesIfChanged<T, std::vector<std::string>, indiDriverT>( p, els, newVals,
indiDriver, newState );
319template <
class indiDriverT>
321 const std::string &el,
322 const pcf::IndiElement::SwitchStateType &newVal,
324 pcf::IndiProperty::PropertyStateType newState = pcf::IndiProperty::Ok )
333 pcf::IndiElement::SwitchStateType oldVal = p[el].getSwitchState();
335 pcf::IndiProperty::PropertyStateType oldState = p.getState();
337 if( oldVal != newVal || oldState != newState )
339 p[el].setSwitchState( newVal );
340 p.setTimeStamp( pcf::TimeStamp() );
341 p.setState( newState );
347 std::cerr <<
"INDI Exception at " << __FILE__ <<
" " << __LINE__ <<
"\n";
348 std::cerr <<
"from " << p.getName() <<
"." << el <<
"\n";
357template <
class indiDriverT>
359 pcf::IndiProperty &p,
360 const std::string &el,
362 pcf::IndiProperty::PropertyStateType newState = pcf::IndiProperty::Ok )
369 std::cerr <<
"INDI error at " << __FILE__ <<
" " << __LINE__ <<
"\n";
370 std::cerr << p.getName() <<
" does not have " << el <<
"\n";
377 bool changed =
false;
378 for(
auto elit = p.getElements().begin(); elit != p.getElements().end(); ++elit )
380 if( elit->first == el )
382 if( elit->second.getSwitchState() != pcf::IndiElement::On )
384 p[elit->first].setSwitchState( pcf::IndiElement::On );
390 if( elit->second.getSwitchState() != pcf::IndiElement::Off )
392 p[elit->first].setSwitchState( pcf::IndiElement::Off );
398 pcf::IndiProperty::PropertyStateType oldState = p.getState();
400 if( changed || oldState != newState )
402 p.setState( newState );
403 p.setTimeStamp( pcf::TimeStamp() );
409 std::cerr <<
"INDI Exception at " << __FILE__ <<
" " << __LINE__ <<
"\n";
410 std::cerr <<
"from " << p.getName() <<
"." << el <<
"\n";
426 std::string &propName,
427 const std::string &key
435 size_t p = key.find(
'.' );
437 if( p == std::string::npos )
451 if( p == key.size() - 1 )
458 devName = key.substr( 0, p );
459 propName = key.substr( p + 1 );
void updateIfChanged(pcf::IndiProperty &p, const std::string &el, const T &newVal, indiDriverT *indiDriver, pcf::IndiProperty::PropertyStateType newState=pcf::IndiProperty::Ok)
Update the value of the INDI element, but only if it has changed.
void updateSelectionSwitchIfChanged(pcf::IndiProperty &p, const std::string &el, indiDriverT *indiDriver, pcf::IndiProperty::PropertyStateType newState=pcf::IndiProperty::Ok)
Update the values of a one-of-many INDI switch vector, but only if it has changed.
int parseIndiKey(std::string &devName, std::string &propName, const std::string &key)
Parse an INDI key into the device and property names.
int addTextElement(pcf::IndiProperty &prop, const std::string &name, const std::string &label="")
Add a standard INDI Text element.
void updateSwitchIfChanged(pcf::IndiProperty &p, const std::string &el, const pcf::IndiElement::SwitchStateType &newVal, indiDriverT *indiDriver, pcf::IndiProperty::PropertyStateType newState=pcf::IndiProperty::Ok)
Update the value of the INDI element, but only if it has changed.
int addNumberElement(pcf::IndiProperty &prop, const std::string &name, const T &min, const T &max, const T &step, const std::string &format, const std::string &label="")
Add a standard INDI Number element.
void updatesIfChanged(pcf::IndiProperty &p, const elVecT &els, const std::vector< T > &newVals, indiDriverT *indiDriver, pcf::IndiProperty::PropertyStateType newState=pcf::IndiProperty::Ok)
Update the elements of an INDI propery, but only if there has been a change in at least one.