Merge pull request #751 from OpenWaterAnalytics/682-request-additional-api-functions-for-enablingdisabling-rules-and-controls-nondestructively

adds api support for enabling/disabling controls and rules
This commit is contained in:
Sam Hatchett
2023-09-13 14:54:16 -04:00
committed by GitHub
11 changed files with 162 additions and 2 deletions

View File

@@ -46,3 +46,5 @@ This document describes the changes and updates that have been made in version 2
- `EN_EMITTERFLOW` can now be used with `EN_getnodevalue` to retrieve a node's emitter flow rate. - `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`). - `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. - 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.

View File

@@ -391,6 +391,9 @@ extern "C" {
int DLLEXPORT ENsetcontrol(int index, int type, int linkIndex, int DLLEXPORT ENsetcontrol(int index, int type, int linkIndex,
EN_API_FLOAT_TYPE setting, int nodeIndex, EN_API_FLOAT_TYPE level); 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 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) #if defined(__cplusplus)
} }
#endif #endif

View File

@@ -1640,6 +1640,23 @@ typedef struct Project *EN_Project;
int DLLEXPORT EN_setcontrol(EN_Project ph, int index, int type, int linkIndex, int DLLEXPORT EN_setcontrol(EN_Project ph, int index, int type, int linkIndex,
double setting, int nodeIndex, double level); 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 EN_TRUE=enabled or EN_FALSE=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 EN_TRUE=enabled or EN_FALSE=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); 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 EN_TRUE=enabled or EN_FALSE=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 EN_TRUE=enabled or EN_FALSE=disabled.
@return an error code.
*/
int DLLEXPORT EN_setruleenabled(EN_Project ph, int index, int enabled);
#if defined(__cplusplus) #if defined(__cplusplus)
} }
#endif #endif

View File

@@ -505,4 +505,7 @@ typedef enum {
#define EN_SET_CLOSED -1.E10 //!< Link set closed indicator #define EN_SET_CLOSED -1.E10 //!< Link set closed indicator
#define EN_SET_OPEN 1.E10 //!< Link set open 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 #endif //EPANET2_ENUMS_H

View File

@@ -5259,6 +5259,42 @@ int DLLEXPORT EN_setcontrol(EN_Project p, int index, int type, int linkIndex,
return 0; 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 != TRUE && enabled != FALSE)
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 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; p->network.Rule[index].priority = priority;
return 0; 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 != TRUE && enabled != FALSE)
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;
}

View File

@@ -786,6 +786,17 @@ int DLLEXPORT ENsetcontrol(int index, int type, int linkIndex,
nodeIndex, level); 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 Rule-Based Controls Functions
@@ -888,3 +899,14 @@ int DLLEXPORT ENsetrulepriority(int index, EN_API_FLOAT_TYPE priority)
{ {
return EN_setrulepriority(_defaultProject, index, 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);
}

View File

@@ -557,6 +557,10 @@ int controls(Project *pr)
{ {
// Make sure that link is defined // Make sure that link is defined
control = &net->Control[i]; control = &net->Control[i];
if (!control->isEnabled)
{
continue;
}
reset = 0; reset = 0;
if ( (k = control->Link) <= 0) continue; if ( (k = control->Link) <= 0) continue;
link = &net->Link[k]; link = &net->Link[k];
@@ -729,7 +733,10 @@ int controltimestep(Project *pr, long *tstep)
{ {
t = 0; t = 0;
control = &net->Control[i]; control = &net->Control[i];
if (!control->isEnabled)
{
continue;
}
// Control depends on a tank level // Control depends on a tank level
if ( (n = control->Node) > 0) if ( (n = control->Node) > 0)
{ {

View File

@@ -943,6 +943,7 @@ int controldata(Project *pr)
control->Time = (long)(3600.0 * time); control->Time = (long)(3600.0 * time);
if (ctltype == TIMEOFDAY) control->Time %= SECperDAY; if (ctltype == TIMEOFDAY) control->Time %= SECperDAY;
control->Grade = level; control->Grade = level;
control->isEnabled = TRUE;
return 0; return 0;
} }

View File

@@ -1232,6 +1232,7 @@ int setcontrol(EN_Project p, int type, int linkIndex, double setting,
control->Setting = s; control->Setting = s;
control->Time = t; control->Time = t;
control->Grade = lvl; control->Grade = lvl;
control->isEnabled = TRUE;
return 0; return 0;
} }

View File

@@ -527,6 +527,11 @@ int checkrules(Project *pr, long dt)
rules->ActionList = NULL; rules->ActionList = NULL;
for (i = 1; i <= net->Nrules; i++) for (i = 1; i <= net->Nrules; i++)
{ {
// skip if the rule is disabled
if (!net->Rule[i].isEnabled)
{
continue;
}
// If premises true, add THEN clauses to action list // If premises true, add THEN clauses to action list
if (evalpremises(pr, i) == TRUE) if (evalpremises(pr, i) == TRUE)
{ {
@@ -684,6 +689,7 @@ void newrule(Project *pr)
rule->ThenActions = NULL; rule->ThenActions = NULL;
rule->ElseActions = NULL; rule->ElseActions = NULL;
rule->priority = 0.0; rule->priority = 0.0;
rule->isEnabled = TRUE;
pr->rules.LastPremise = NULL; pr->rules.LastPremise = NULL;
pr->rules.LastThenAction = NULL; pr->rules.LastThenAction = NULL;
pr->rules.LastElseAction = NULL; pr->rules.LastElseAction = NULL;

View File

@@ -474,6 +474,7 @@ typedef struct // Control Statement
double Setting; // new link setting double Setting; // new link setting
StatusType Status; // new link status StatusType Status; // new link status
ControlType Type; // control type ControlType Type; // control type
int isEnabled; // control enabled?
} Scontrol; } Scontrol;
typedef struct // Field Object of Report Table typedef struct // Field Object of Report Table
@@ -525,6 +526,7 @@ typedef struct // Control Rule Structure
{ {
char label[MAXID+1]; // rule label char label[MAXID+1]; // rule label
double priority; // priority level double priority; // priority level
int isEnabled; // is the rule enabled?
Spremise *Premises; // list of premises Spremise *Premises; // list of premises
Saction *ThenActions; // list of THEN actions Saction *ThenActions; // list of THEN actions
Saction *ElseActions; // list of ELSE actions Saction *ElseActions; // list of ELSE actions