From 06a43cdb4e1096dd3b68de8f34485faf21a25fb2 Mon Sep 17 00:00:00 2001 From: Sam Hatchett Date: Tue, 12 Sep 2023 14:51:44 -0400 Subject: [PATCH 1/4] 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 From d0ab568a5d6a27b454bc0b65e146cfe04ca95783 Mon Sep 17 00:00:00 2001 From: Sam Hatchett Date: Wed, 13 Sep 2023 09:14:57 -0400 Subject: [PATCH 2/4] using int/bool convention instead of new enum type --- include/epanet2_enums.h | 3 +++ src/epanet.c | 4 ++-- src/hydraul.c | 4 ++-- src/input3.c | 2 +- src/project.c | 2 +- src/rules.c | 4 ++-- src/types.h | 9 ++------- 7 files changed, 13 insertions(+), 15 deletions(-) diff --git a/include/epanet2_enums.h b/include/epanet2_enums.h index dec12f5..557f48f 100644 --- a/include/epanet2_enums.h +++ b/include/epanet2_enums.h @@ -505,4 +505,7 @@ typedef enum { #define EN_SET_CLOSED -1.E10 //!< Link set closed indicator #define EN_SET_OPEN 1.E10 //!< Link set open indicator +#define EN_FALSE 0 // boolean false +#define EN_TRUE 1 // boolean true + #endif //EPANET2_ENUMS_H diff --git a/src/epanet.c b/src/epanet.c index d2c4d11..bbbfb62 100644 --- a/src/epanet.c +++ b/src/epanet.c @@ -5283,7 +5283,7 @@ int DLLEXPORT EN_setcontrolenabled(EN_Project p, int index, int enabled) Scontrol *control; // Check for valid arguments - if (enabled != ENABLED && enabled != DISABLED) + if (enabled != TRUE && enabled != FALSE) return 202; // illegal numeric value if (!p->Openflag) return 102; @@ -5742,7 +5742,7 @@ int DLLEXPORT EN_setruleenabled(EN_Project p, int index, int enabled) Srule *rule; // Check for valid arguments - if (enabled != ENABLED && enabled != DISABLED) + if (enabled != TRUE && enabled != FALSE) return 202; // illegal numeric value if (!p->Openflag) return 102; diff --git a/src/hydraul.c b/src/hydraul.c index 9e5aadb..96433f3 100755 --- a/src/hydraul.c +++ b/src/hydraul.c @@ -557,7 +557,7 @@ int controls(Project *pr) { // Make sure that link is defined control = &net->Control[i]; - if (control->isEnabled == DISABLED) + if (!control->isEnabled) { continue; } @@ -733,7 +733,7 @@ int controltimestep(Project *pr, long *tstep) { t = 0; control = &net->Control[i]; - if (control->isEnabled == DISABLED) + if (!control->isEnabled) { continue; } diff --git a/src/input3.c b/src/input3.c index 304a77d..713c07e 100644 --- a/src/input3.c +++ b/src/input3.c @@ -943,7 +943,7 @@ int controldata(Project *pr) control->Time = (long)(3600.0 * time); if (ctltype == TIMEOFDAY) control->Time %= SECperDAY; control->Grade = level; - control->isEnabled = ENABLED; + control->isEnabled = TRUE; return 0; } diff --git a/src/project.c b/src/project.c index 0877427..258b9b0 100644 --- a/src/project.c +++ b/src/project.c @@ -1232,7 +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; + control->isEnabled = TRUE; return 0; } diff --git a/src/rules.c b/src/rules.c index bb4f269..99d0a02 100644 --- a/src/rules.c +++ b/src/rules.c @@ -528,7 +528,7 @@ int checkrules(Project *pr, long dt) for (i = 1; i <= net->Nrules; i++) { // skip if the rule is disabled - if (net->Rule[i].isEnabled == DISABLED) + if (!net->Rule[i].isEnabled) { continue; } @@ -689,7 +689,7 @@ void newrule(Project *pr) rule->ThenActions = NULL; rule->ElseActions = NULL; rule->priority = 0.0; - rule->isEnabled = ENABLED; + rule->isEnabled = TRUE; pr->rules.LastPremise = NULL; pr->rules.LastThenAction = NULL; pr->rules.LastElseAction = NULL; diff --git a/src/types.h b/src/types.h index 6b333c4..ff7c359 100755 --- a/src/types.h +++ b/src/types.h @@ -196,11 +196,6 @@ 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 @@ -479,7 +474,7 @@ typedef struct // Control Statement double Setting; // new link setting StatusType Status; // new link status ControlType Type; // control type - EnabledType isEnabled; // control enabled? + int isEnabled; // control enabled? } Scontrol; typedef struct // Field Object of Report Table @@ -531,7 +526,7 @@ typedef struct // Control Rule Structure { char label[MAXID+1]; // rule label double priority; // priority level - EnabledType isEnabled; // is the rule enabled? + int isEnabled; // is the rule enabled? Spremise *Premises; // list of premises Saction *ThenActions; // list of THEN actions Saction *ElseActions; // list of ELSE actions From 8b28307ecd0a06e88bb798f6f896dfdb77d05ac4 Mon Sep 17 00:00:00 2001 From: Sam Hatchett Date: Wed, 13 Sep 2023 09:18:08 -0400 Subject: [PATCH 3/4] clarifying documentation --- include/epanet2_2.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/epanet2_2.h b/include/epanet2_2.h index 2b44c1d..a25036c 100644 --- a/include/epanet2_2.h +++ b/include/epanet2_2.h @@ -1644,7 +1644,7 @@ typedef struct Project *EN_Project; @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. + @param out_enabled the control will be either EN_TRUE=enabled or EN_FALSE=disabled. @return an error code. */ int DLLEXPORT EN_getcontrolenabled(EN_Project ph, int index, int *out_enabled); @@ -1653,7 +1653,7 @@ typedef struct Project *EN_Project; @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. + @param enabled set the control to either EN_TRUE=enabled or EN_FALSE=disabled. @return an error code. */ int DLLEXPORT EN_setcontrolenabled(EN_Project ph, int index, int enabled); @@ -1845,7 +1845,7 @@ typedef struct Project *EN_Project; @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. + @param out_enabled the rule will be either EN_TRUE=enabled or EN_FALSE=disabled. @return an error code. */ int DLLEXPORT EN_getruleenabled(EN_Project ph, int index, int *out_enabled); @@ -1854,7 +1854,7 @@ typedef struct Project *EN_Project; @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. + @param enabled set the rule to either EN_TRUE=enabled or EN_FALSE=disabled. @return an error code. */ int DLLEXPORT EN_setruleenabled(EN_Project ph, int index, int enabled); From 0754d08721d017efb440cb0ae6239f87604f4a58 Mon Sep 17 00:00:00 2001 From: Sam Hatchett Date: Wed, 13 Sep 2023 14:30:57 -0400 Subject: [PATCH 4/4] Update ReleaseNotes2_3.md --- ReleaseNotes2_3.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ReleaseNotes2_3.md b/ReleaseNotes2_3.md index d4858c5..cb8f151 100644 --- a/ReleaseNotes2_3.md +++ b/ReleaseNotes2_3.md @@ -45,4 +45,6 @@ This document describes the changes and updates that have been made in version 2 - `EN_SET_CLOSED` and `EN_SET_OPEN` constants were added that can be used with `EN_setcontrol` to fix the status of pipes and valves to completely closed or completely open. - `EN_EMITTERFLOW` can now be used with `EN_getnodevalue` to retrieve a node's emitter flow rate. - `EN_STATUS_REPORT` can now be used with `EN_getoption` and `EN_setoption` to get or set the type of status report that EPANET will generate (`EN_NO_REPORT`, `EN_NORMAL_REPORT` or `EN_FULL_REPORT`). - - A possible parser error that could result in a Trace Node ID in an input file not being recognized was fixed. \ No newline at end of file + - A possible parser error that could result in a Trace Node ID in an input file not being recognized was fixed. + - Additional API functions for enabling/disabling controls and rules were added. + \ No newline at end of file