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_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.
- 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,
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

View File

@@ -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 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);
/**
@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)
}
#endif

View File

@@ -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

View File

@@ -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 != 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
@@ -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 != 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);
}
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);
}

View File

@@ -557,6 +557,10 @@ int controls(Project *pr)
{
// Make sure that link is defined
control = &net->Control[i];
if (!control->isEnabled)
{
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)
{
continue;
}
// Control depends on a tank level
if ( (n = control->Node) > 0)
{

View File

@@ -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 = TRUE;
return 0;
}

View File

@@ -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 = TRUE;
return 0;
}

View File

@@ -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)
{
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 = TRUE;
pr->rules.LastPremise = NULL;
pr->rules.LastThenAction = NULL;
pr->rules.LastElseAction = NULL;

View File

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