7 #ifndef stateRuleEngine_indiCompRuleConfig_hpp
8 #define stateRuleEngine_indiCompRuleConfig_hpp
19 typedef std::map<std::string, indiCompRule*>
ruleMapT;
20 typedef std::map<std::string, pcf::IndiProperty*>
propMapT;
27 auto rit =
rules.begin();
28 while(rit !=
rules.end())
34 auto pit =
props.begin();
35 while(pit !=
props.end())
59 std::string & element,
61 const std::string & section,
62 const std::string & propkey,
63 const std::string & elkey,
64 const pcf::IndiProperty::Type & type,
65 mx::app::appConfigurator & config
69 config.configUnused(property, mx::app::iniFile::makeKey(section, propkey ));
71 if(maps.
props.count(property) > 0)
74 if(maps.
props[property]->getType() != type)
76 mxThrowException(mx::err::invalidconfig,
"extracPropRule",
"property " + property +
" exists but is not correct type");
79 *prop = maps.
props[property];
84 *prop =
new pcf::IndiProperty(type);
85 maps.
props.insert(std::pair<std::string, pcf::IndiProperty*>({property, *prop}));
90 config.configUnused(element, mx::app::iniFile::makeKey(section, elkey));
99 std::map<std::string, ruleRuleKeys> & rrkMap,
100 mx::app::appConfigurator & config
103 std::vector<std::string> sections;
105 config.unusedSections(sections);
107 if( sections.size() == 0 )
109 mxThrowException(mx::err::invalidconfig,
"loadRuleConfig",
"no rules found in config");
113 for(
size_t i=0; i< sections.size(); ++i)
115 bool ruleTypeSet = config.isSetUnused(mx::app::iniFile::makeKey(sections[i],
"ruleType" ));
118 if( !ruleTypeSet )
continue;
121 if(maps.
rules.count(sections[i]) != 0)
123 mxThrowException(mx::err::invalidconfig,
"loadRuleConfig",
"duplicate rule: " + sections[i]);
126 std::string ruleType;
127 config.configUnused(ruleType, mx::app::iniFile::makeKey(sections[i],
"ruleType" ));
129 std::string priostr=
"none";
130 config.configUnused(priostr, mx::app::iniFile::makeKey(sections[i],
"priority" ));
134 config.configUnused(message, mx::app::iniFile::makeKey(sections[i],
"message" ));
136 std::string compstr=
"Eq";
137 config.configUnused(compstr, mx::app::iniFile::makeKey(sections[i],
"comp" ));
143 maps.
rules.insert(std::pair<std::string, indiCompRule*>({sections[i], nvr}));
149 pcf::IndiProperty * prop =
nullptr;
152 extractRuleProp( &prop, element, maps, sections[i],
"property",
"element", pcf::IndiProperty::Number, config );
156 double target = nvr->
target();
157 config.configUnused(target, mx::app::iniFile::makeKey(sections[i],
"target" ));
160 double tol = nvr->
tol();
161 config.configUnused(tol, mx::app::iniFile::makeKey(sections[i],
"tol" ));
167 maps.
rules.insert(std::pair<std::string, indiCompRule*>({sections[i], tvr}));
173 pcf::IndiProperty * prop =
nullptr;
176 extractRuleProp( &prop, element, maps, sections[i],
"property",
"element", pcf::IndiProperty::Text, config );
181 std::string target = tvr->
target();
182 config.configUnused(target, mx::app::iniFile::makeKey(sections[i],
"target" ));
189 maps.
rules.insert(std::pair<std::string, indiCompRule*>({sections[i], svr}));
195 pcf::IndiProperty * prop =
nullptr;
198 extractRuleProp( &prop, element, maps, sections[i],
"property",
"element", pcf::IndiProperty::Switch, config );
202 std::string target =
"On";
203 config.configUnused(target, mx::app::iniFile::makeKey(sections[i],
"target" ));
209 maps.
rules.insert(std::pair<std::string, indiCompRule*>({sections[i], nvr}));
215 pcf::IndiProperty * prop1;
216 std::string element1;
218 extractRuleProp( &prop1, element1, maps, sections[i],
"property1",
"element1", pcf::IndiProperty::Number, config );
222 pcf::IndiProperty * prop2;
223 std::string element2;
225 extractRuleProp( &prop2, element2, maps, sections[i],
"property2",
"element2", pcf::IndiProperty::Number, config );
232 maps.
rules.insert(std::pair<std::string, indiCompRule*>({sections[i], tvr}));
238 pcf::IndiProperty * prop1;
239 std::string element1;
241 extractRuleProp( &prop1, element1, maps, sections[i],
"property1",
"element1", pcf::IndiProperty::Text, config );
245 pcf::IndiProperty * prop2;
246 std::string element2;
248 extractRuleProp( &prop2, element2, maps, sections[i],
"property2",
"element2", pcf::IndiProperty::Text, config );
255 maps.
rules.insert(std::pair<std::string, indiCompRule*>({sections[i], svr}));
261 pcf::IndiProperty * prop1;
262 std::string element1;
264 extractRuleProp( &prop1, element1, maps, sections[i],
"property1",
"element1", pcf::IndiProperty::Switch, config );
268 pcf::IndiProperty * prop2;
269 std::string element2;
271 extractRuleProp( &prop2, element2, maps, sections[i],
"property2",
"element2", pcf::IndiProperty::Switch, config );
279 if(rrkMap.count(sections[i]) > 0)
282 mxThrowException(mx::err::invalidconfig,
"loadRuleConfig",
"duplicate ruleRule: " + sections[i]);
286 maps.
rules.insert(std::pair<std::string, indiCompRule*>({sections[i], rcr}));
293 config.configUnused(rrk.
rule1, mx::app::iniFile::makeKey(sections[i],
"rule1" ));
296 mxThrowException(mx::err::invalidconfig,
"loadRuleConfig",
"rule1 for ruleVal rule " + sections[i] +
" not found");
298 if(rrk.
rule1 == sections[i])
300 mxThrowException(mx::err::invalidconfig,
"loadRuleConfig",
"rule1 for ruleVal rule " + sections[i] +
" can't equal rule name");
303 config.configUnused(rrk.
rule2, mx::app::iniFile::makeKey(sections[i],
"rule2" ));
306 mxThrowException(mx::err::invalidconfig,
"loadRuleConfig",
"rule2 for ruleVal rule " + sections[i] +
" not found");
308 if(rrk.
rule2 == sections[i])
310 mxThrowException(mx::err::invalidconfig,
"loadRuleConfig",
"rule2 for ruleVal rule " + sections[i] +
" can't equal rule name");
313 rrkMap.insert(std::pair<std::string, ruleRuleKeys>(sections[i], rrk));
317 mxThrowException(mx::err::notimpl,
"loadRuleConfig",
"unknown rule type " + ruleType +
" in " + sections[i]);
327 std::map<std::string, ruleRuleKeys> & rrkMap
331 auto it=rrkMap.begin();
332 while(
it != rrkMap.end())
334 if( maps.
rules.count(
it->first) == 0 )
336 mxThrowException(mx::err::invalidconfig,
"loadRuleConfig",
"rule parsing error for " +
it->first);
339 if( maps.
rules.count(
it->second.rule1) == 0 )
341 mxThrowException(mx::err::invalidconfig,
"loadRuleConfig",
"rule1 " +
it->second.rule1 +
" not found for ruleVal rule " +
it->first );
344 if( maps.
rules.count(
it->second.rule2) == 0 )
346 mxThrowException(mx::err::invalidconfig,
"loadRuleConfig",
"rule2 " +
it->second.rule2 +
" not found for ruleVal rule " +
it->first );
355 catch(
const std::exception & e)
357 mxThrowException(mx::err::invalidconfig,
"loadRuleConfig",
"error casting " +
it->first +
": " + e.what() );
362 mxThrowException(mx::err::invalidconfig,
"loadRuleConfig",
it->first +
" is not a ruleVal rule but has rules" );
void loadRuleConfig(indiRuleMaps &maps, std::map< std::string, ruleRuleKeys > &rrkMap, mx::app::appConfigurator &config)
Load the rule and properties maps for a rule engine from a configuration file.
void finalizeRuleValRules(indiRuleMaps &maps, std::map< std::string, ruleRuleKeys > &rrkMap)
Finalize ruleVal rules.
void extractRuleProp(pcf::IndiProperty **prop, std::string &element, indiRuleMaps &maps, const std::string §ion, const std::string &propkey, const std::string &elkey, const pcf::IndiProperty::Type &type, mx::app::appConfigurator &config)
Extract a property from a rule configuration.
The rules for the MagAO-X stateRuleEngine.
ruleComparison
Logical comparisons for the INDI rules.
ruleComparison string2comp(const std::string &cstr)
Get the ruleComparison member from a string representation.
rulePriority string2priority(const std::string &pstr)
Get the rulePriority member from a string representation.
rulePriority
Reporting priorities for rules.
Compare two elements based on their numeric values.
static constexpr char name[]
Name of this rule, used by config system.
Compare two elements based on their switch values.
static constexpr char name[]
Name of this rule, used by config system.
Compare two elements based on their text values.
static constexpr char name[]
Name of this rule, used by config system.
void priority(const rulePriority &p)
Set priority of this rule.
void comparison(const ruleComparison &c)
Set the comparison for this rule.
void message(const std::string &m)
Set the message.
Structure to provide management of the rule and property maps.
std::map< std::string, pcf::IndiProperty * > propMapT
std::map< std::string, indiCompRule * > ruleMapT
Compare the value of a number element to a target.
void target(const double &tgt)
Set the target for the comparison.
void tol(const double &t)
Set the tolerance.
static constexpr char name[]
Name of this rule, used by config system.
void property(pcf::IndiProperty *property)
Set the property pointer.
void element(const std::string &el)
Set the element name.
A rule to compare two rules.
void rule2(indiCompRule *r)
Set the pointer to the second rule.
void rule1(indiCompRule *r)
Set the pointer to the first rule.
static constexpr char name[]
Name of this rule, used by config system.
Compare the value of a switch to a target value.
void target(const pcf::IndiElement::SwitchStateType &ss)
Set the target for the comparison.
static constexpr char name[]
Name of this rule, used by config system.
void property1(pcf::IndiProperty *property)
Set the first property pointer.
void element2(const std::string &el)
Set the second element name.
void element1(const std::string &el)
Set the first element name.
void property2(pcf::IndiProperty *property)
Set the second property pointer.
Compare the value of a text element to a target value.
void target(const std::string &target)
Set the target for the comparison.
static constexpr char name[]
Name of this rule, used by config system.