From 06a43cdb4e1096dd3b68de8f34485faf21a25fb2 Mon Sep 17 00:00:00 2001 From: Sam Hatchett Date: Tue, 12 Sep 2023 14:51:44 -0400 Subject: [PATCH] adds api support for enabling/disabling controls and rules --- include/epanet2.h | 7 +++++ include/epanet2_2.h | 35 +++++++++++++++++++++ src/epanet.c | 74 +++++++++++++++++++++++++++++++++++++++++++++ src/epanet2.c | 22 ++++++++++++++ src/hydraul.c | 9 +++++- src/input3.c | 1 + src/project.c | 1 + src/rules.c | 6 ++++ src/types.h | 7 +++++ 9 files changed, 161 insertions(+), 1 deletion(-) diff --git a/include/epanet2.h b/include/epanet2.h index 36a1f0f..25651f0 100644 --- a/include/epanet2.h +++ b/include/epanet2.h @@ -391,6 +391,9 @@ extern "C" { int DLLEXPORT ENsetcontrol(int index, int type, int linkIndex, EN_API_FLOAT_TYPE setting, int nodeIndex, EN_API_FLOAT_TYPE level); + int DLLEXPORT ENgetcontrolenabled(int index, int *out_enabled); + + int DLLEXPORT ENsetcontrolenabled(int index, int enabled); /******************************************************************** @@ -436,6 +439,10 @@ extern "C" { int DLLEXPORT ENsetrulepriority(int index, EN_API_FLOAT_TYPE priority); + int DLLEXPORT ENgetruleenabled(int index, int *out_enabled); + + int DLLEXPORT ENsetruleenabled(int index, int enabled); + #if defined(__cplusplus) } #endif diff --git a/include/epanet2_2.h b/include/epanet2_2.h index 62e3d1a..2b44c1d 100644 --- a/include/epanet2_2.h +++ b/include/epanet2_2.h @@ -1640,6 +1640,23 @@ typedef struct Project *EN_Project; int DLLEXPORT EN_setcontrol(EN_Project ph, int index, int type, int linkIndex, double setting, int nodeIndex, double level); + /** + @brief Gets the enabled status of a simple control. + @param ph an EPANET project handle. + @param index the control's index (starting from 1). + @param out_enabled the control will be either enabled or disabled. + @return an error code. + */ + int DLLEXPORT EN_getcontrolenabled(EN_Project ph, int index, int *out_enabled); + + /** + @brief Sets the enabled status of a simple control. + @param ph an EPANET project handle. + @param index the control's index (starting from 1). + @param enabled set the control to either enabled or disabled. + @return an error code. + */ + int DLLEXPORT EN_setcontrolenabled(EN_Project ph, int index, int enabled); /******************************************************************** @@ -1824,6 +1841,24 @@ typedef struct Project *EN_Project; */ int DLLEXPORT EN_setrulepriority(EN_Project ph, int index, double priority); + /** + @brief Gets the enabled status of a rule-based control. + @param ph an EPANET project handle. + @param index the rule's index (starting from 1). + @param out_enabled the rule will be either enabled or disabled. + @return an error code. + */ + int DLLEXPORT EN_getruleenabled(EN_Project ph, int index, int *out_enabled); + + /** + @brief Sets the enabled status of a rule-based control. + @param ph an EPANET project handle. + @param index the rule's index (starting from 1). + @param enabled set the rule to either enabled or disabled. + @return an error code. + */ + int DLLEXPORT EN_setruleenabled(EN_Project ph, int index, int enabled); + #if defined(__cplusplus) } #endif diff --git a/src/epanet.c b/src/epanet.c index a654420..d2c4d11 100644 --- a/src/epanet.c +++ b/src/epanet.c @@ -5259,6 +5259,42 @@ int DLLEXPORT EN_setcontrol(EN_Project p, int index, int type, int linkIndex, return 0; } + +int DLLEXPORT EN_getcontrolenabled(EN_Project p, int index, int *enabled) +{ + Network *net = &p->network; + Scontrol *control; + + // Check for valid arguments + if (!p->Openflag) + return 102; + if (index <= 0 || index > net->Ncontrols) + return 241; + + control = &net->Control[index]; + *enabled = control->isEnabled; + return 0; +} + + +int DLLEXPORT EN_setcontrolenabled(EN_Project p, int index, int enabled) +{ + Network *net = &p->network; + Scontrol *control; + + // Check for valid arguments + if (enabled != ENABLED && enabled != DISABLED) + return 202; // illegal numeric value + if (!p->Openflag) + return 102; + if (index <= 0 || index > net->Ncontrols) + return 241; + + control = &net->Control[index]; + control->isEnabled = enabled; + return 0; +} + /******************************************************************** Rule-Based Controls Functions @@ -5681,3 +5717,41 @@ int DLLEXPORT EN_setrulepriority(EN_Project p, int index, double priority) p->network.Rule[index].priority = priority; return 0; } + + +int DLLEXPORT EN_getruleenabled(EN_Project p, int index, int *enabled) +{ + Network *net = &p->network; + Srule *rule; + + // Check for valid arguments + if (!p->Openflag) + return 102; + if (index <= 0 || index > net->Nrules) + return 241; + + rule = &net->Rule[index]; + *enabled = rule->isEnabled; + return 0; +} + + +int DLLEXPORT EN_setruleenabled(EN_Project p, int index, int enabled) +{ + Network *net = &p->network; + Srule *rule; + + // Check for valid arguments + if (enabled != ENABLED && enabled != DISABLED) + return 202; // illegal numeric value + if (!p->Openflag) + return 102; + if (index <= 0 || index > net->Nrules) + return 241; + + rule = &net->Rule[index]; + rule->isEnabled = enabled; + return 0; +} + + diff --git a/src/epanet2.c b/src/epanet2.c index 53d1732..d814892 100644 --- a/src/epanet2.c +++ b/src/epanet2.c @@ -786,6 +786,17 @@ int DLLEXPORT ENsetcontrol(int index, int type, int linkIndex, nodeIndex, level); } + +int DLLEXPORT ENgetcontrolenabled(int index, int *out_enabled) +{ + return EN_getcontrolenabled(_defaultProject, index, out_enabled); +} + +int DLLEXPORT ENsetcontrolenabled(int index, int enabled) +{ + return EN_setcontrolenabled(_defaultProject, index, enabled); +} + /******************************************************************** Rule-Based Controls Functions @@ -888,3 +899,14 @@ int DLLEXPORT ENsetrulepriority(int index, EN_API_FLOAT_TYPE priority) { return EN_setrulepriority(_defaultProject, index, priority); } + + +int DLLEXPORT ENgetruleenabled(int index, int *out_enabled) +{ + return EN_getruleenabled(_defaultProject, index, out_enabled); +} + +int DLLEXPORT ENsetruleenabled(int index, int enabled) +{ + return EN_setruleenabled(_defaultProject, index, enabled); +} diff --git a/src/hydraul.c b/src/hydraul.c index 93907ec..9e5aadb 100755 --- a/src/hydraul.c +++ b/src/hydraul.c @@ -557,6 +557,10 @@ int controls(Project *pr) { // Make sure that link is defined control = &net->Control[i]; + if (control->isEnabled == DISABLED) + { + continue; + } reset = 0; if ( (k = control->Link) <= 0) continue; link = &net->Link[k]; @@ -729,7 +733,10 @@ int controltimestep(Project *pr, long *tstep) { t = 0; control = &net->Control[i]; - + if (control->isEnabled == DISABLED) + { + continue; + } // Control depends on a tank level if ( (n = control->Node) > 0) { diff --git a/src/input3.c b/src/input3.c index 6dfd1fe..304a77d 100644 --- a/src/input3.c +++ b/src/input3.c @@ -943,6 +943,7 @@ int controldata(Project *pr) control->Time = (long)(3600.0 * time); if (ctltype == TIMEOFDAY) control->Time %= SECperDAY; control->Grade = level; + control->isEnabled = ENABLED; return 0; } diff --git a/src/project.c b/src/project.c index aba50c8..0877427 100644 --- a/src/project.c +++ b/src/project.c @@ -1232,6 +1232,7 @@ int setcontrol(EN_Project p, int type, int linkIndex, double setting, control->Setting = s; control->Time = t; control->Grade = lvl; + control->isEnabled = ENABLED; return 0; } diff --git a/src/rules.c b/src/rules.c index 4eaf3f5..bb4f269 100644 --- a/src/rules.c +++ b/src/rules.c @@ -527,6 +527,11 @@ int checkrules(Project *pr, long dt) rules->ActionList = NULL; for (i = 1; i <= net->Nrules; i++) { + // skip if the rule is disabled + if (net->Rule[i].isEnabled == DISABLED) + { + continue; + } // If premises true, add THEN clauses to action list if (evalpremises(pr, i) == TRUE) { @@ -684,6 +689,7 @@ void newrule(Project *pr) rule->ThenActions = NULL; rule->ElseActions = NULL; rule->priority = 0.0; + rule->isEnabled = ENABLED; pr->rules.LastPremise = NULL; pr->rules.LastThenAction = NULL; pr->rules.LastElseAction = NULL; diff --git a/src/types.h b/src/types.h index ae837ab..6b333c4 100755 --- a/src/types.h +++ b/src/types.h @@ -196,6 +196,11 @@ typedef enum { TIMEOFDAY // act when time of day occurs } ControlType; +typedef enum { + DISABLED, + ENABLED +} EnabledType; + typedef enum { XHEAD, // pump cannot deliver head (closed) TEMPCLOSED, // temporarily closed @@ -474,6 +479,7 @@ typedef struct // Control Statement double Setting; // new link setting StatusType Status; // new link status ControlType Type; // control type + EnabledType isEnabled; // control enabled? } Scontrol; typedef struct // Field Object of Report Table @@ -525,6 +531,7 @@ typedef struct // Control Rule Structure { char label[MAXID+1]; // rule label double priority; // priority level + EnabledType isEnabled; // is the rule enabled? Spremise *Premises; // list of premises Saction *ThenActions; // list of THEN actions Saction *ElseActions; // list of ELSE actions