Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 38 additions & 2 deletions examples/scheduler_example1.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,16 +136,52 @@ main(int argc, char** argv)

Thread workerThread = Thread_create(outputWorkerThread, NULL, false);

printf("Target for @Control/ActPow_FSCC1: %s\n", Scheduler_getCtlEntityRef(sched, "@Control/ActPow_FSCC1"));

IedServer_start(server, 102);

if (IedServer_isRunning(server)) {
int count = 0;

if (IedServer_isRunning(server))
{
running = true;

Thread_start(workerThread);

while (running) {
while (running)
{
if (count % 50 == 0) {
printf("Create forecast 24 h...\n");

uint64_t currentTime = Hal_getTimeInMs();

LinkedList forecast = Scheduler_createForecast(sched, "@Control/ActPow_FSCC1", currentTime, currentTime + 86400000);

if (forecast)
{
LinkedList forecastElem = LinkedList_getNext(forecast);

while (forecastElem)
{
ScheduleEvent event = (ScheduleEvent)LinkedList_getData(forecastElem);

char valueBuf[50];
if (ScheduleEvent_getValue(event))
MmsValue_printToBuffer(ScheduleEvent_getValue(event), valueBuf, 50);
else
valueBuf[0] = 0;

printf("time: %lu value: %s\n", ScheduleEvent_getTime(event), valueBuf);

forecastElem = LinkedList_getNext(forecastElem);
}

LinkedList_destroyDeep(forecast, (LinkedListValueDeleteFunction)ScheduleEvent_destroy);
}
}

Thread_sleep(100);
count++;
}
}
else {
Expand Down
6 changes: 3 additions & 3 deletions models/model.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ DA(multiplier 0 12 4 1 0)=3;
DA(d 0 20 5 0 0);
}
DO(CtlEnt 0){
DA(setSrcRef 0 19 2 1 0)="@Control/ActPow_GGIO1.AnOut1.mxVal.f";
DA(setSrcRef 0 19 2 1 0)="@Control/ActPow_GGIO1.AnOut1";
}
DO(Schd01 0){
DA(setSrcRef 0 19 2 1 0)="@Control/ActPow_FSCH01";
Expand Down Expand Up @@ -208,7 +208,7 @@ DA(multiplier 0 12 4 1 0)=3;
DA(d 0 20 5 0 0);
}
DO(CtlEnt 0){
DA(setSrcRef 0 19 2 1 0)="@Control/MaxPow_GGIO1.AnOut1.mxVal.f";
DA(setSrcRef 0 19 2 1 0)="@Control/MaxPow_GGIO1.AnOut1";
}
DO(Schd01 0){
DA(setSrcRef 0 19 2 1 0)="@Control/MaxPow_FSCH01";
Expand Down Expand Up @@ -261,7 +261,7 @@ DA(q 0 23 0 2 0);
DA(t 0 22 0 0 0);
}
DO(CtlEnt 0){
DA(setSrcRef 0 19 2 1 0)="@Control/OnOff_GGIO1.SPCSO1.stVal";
DA(setSrcRef 0 19 2 1 0)="@Control/OnOff_GGIO1.SPCSO1";
}
DO(Schd01 0){
DA(setSrcRef 0 19 2 1 0)="@Control/OnOff_FSCH01";
Expand Down
92 changes: 90 additions & 2 deletions src/scheduler/der_scheduler.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,10 @@ Scheduler_destroy(Scheduler self)

LinkedList_destroyDeep(self->schedules, (LinkedListValueDeleteFunction)Schedule_destroy);

if (self->storage) {
SchedulerStorage_destroy(self->storage);
}

free(self);
}
}
Expand All @@ -247,6 +251,54 @@ Scheduler_enableScheduleControl(Scheduler self, const char* scheduleRef, bool en
}
}

LinkedList
Scheduler_createScheduleForecast(Scheduler self, const char* scheduleRef, uint64_t startTime, uint64_t endTime)
{
Schedule schedule = Scheduler_getScheduleByObjRef(self, scheduleRef);

if (schedule)
{
return Schedule_runSchedule(schedule, startTime, endTime);
}
else {
printf("WARN: Schedule %s not found\n", scheduleRef);

return NULL;
}
}

LinkedList
Scheduler_createForecast(Scheduler self, const char* schedCtrlRef, uint64_t startTime, uint64_t endTime)
{
ScheduleController scc = Scheduler_getScheduleControllerByObjRef(self, schedCtrlRef);

if (scc)
{
return ScheduleController_createForecast(scc, startTime, endTime);
}
else {
printf("WARN: Schedule controller %s not found\n", schedCtrlRef);

return NULL;
}
}

const char*
Scheduler_getCtlEntityRef(Scheduler self, const char* schedCtrlRef)
{
ScheduleController scc = Scheduler_getScheduleControllerByObjRef(self, schedCtrlRef);

if (scc)
{
return ScheduleController_getCtlEntRef(scc);
}
else {
printf("WARN: Schedule controller %s not found\n", schedCtrlRef);

return NULL;
}
}

bool
Scheduler_enableSchedule(Scheduler self, const char* scheduleRef, bool enable)
{
Expand Down Expand Up @@ -316,8 +368,8 @@ Scheduler_getScheduleByObjRef(Scheduler self, const char* objRef)
{
Schedule matchingSchedule = NULL;

if (objRef && objRef[0] != 0) {

if (objRef && objRef[0] != 0)
{
bool withoutIedName = false;

if (objRef[0] == '@') {
Expand Down Expand Up @@ -345,3 +397,39 @@ Scheduler_getScheduleByObjRef(Scheduler self, const char* objRef)

return matchingSchedule;
}

ScheduleController
Scheduler_getScheduleControllerByObjRef(Scheduler self, const char* objRef)
{
ScheduleController matchingController = NULL;

if (objRef && objRef[0] != 0)
{
bool withoutIedName = false;

if (objRef[0] == '@') {
withoutIedName = true;
objRef = objRef + 1;
}

LinkedList controllerElem = LinkedList_getNext(self->scheduleController);

while (controllerElem)
{
ScheduleController controller = (ScheduleController)LinkedList_getData(controllerElem);

char controllerObjRefBuf[130];

ModelNode_getObjectReferenceEx((ModelNode*)controller->controllerLn, controllerObjRefBuf, withoutIedName);

if (!strcmp(objRef, controllerObjRefBuf)) {
matchingController = controller;
break;
}

controllerElem = LinkedList_getNext(controllerElem);
}
}

return matchingController;
}
60 changes: 60 additions & 0 deletions src/scheduler/der_scheduler.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,36 @@ extern "C" {

typedef struct sScheduler* Scheduler;

/**
* \brief Specify the log level for the library internal logging
*/
typedef enum {
/**
* log level DEBUG - shows the most information (useful for debugging applications)
*/
SCHEDULER_LOG_DEBUG = 1,

/**
* log level INFO - show informational messages (useful to trace communication problems)
*/
SCHEDULER__LOG_INFO = 2,

/**
* log level WARNING - show only errors and warning message that indicate wrong configuration
*/
SCHEDULER__LOG_WARNING = 3,

/**
* log level ERROR - show critical problems and communication errors
*/
SCHEDULER__LOG_ERROR = 4,

/**
* log level NONE - don't show any log messages
*/
SCHEDULER_LOG_NONE = 5
} Scheduler_LogLevel;

/**
* @brief Create a new Scheduler instance
*
Expand Down Expand Up @@ -89,6 +119,25 @@ Scheduler_getTargetValue(Scheduler self, const char* controllerRef, char* target
void
Scheduler_enableScheduleControl(Scheduler self, const char* scheduleRef, bool enable);

LinkedList /* <ScheduleEvent> */
Scheduler_createScheduleForecast(Scheduler self, const char* scheduleRef, uint64_t startTime, uint64_t endTime);

/**
* @brief Create a schedule forecast for the specified schedule controller and time period
*
* @param self the scheduler instance
* @param schedCtrRef the object reference of the ScheduleController (@LDInst/LN)
* @param startTime the start time of the forecast time period (in ms since Epoch)
* @param endTime the end time of the forecast time period (in ms since Epoch)
*
* @return the list of schedule events (value changes) during the time period
*/
LinkedList /* <ScheduleEvent> */
Scheduler_createForecast(Scheduler self, const char* schedCtrRef, uint64_t startTime, uint64_t endTime);

const char*
Scheduler_getCtlEntityRef(Scheduler self, const char* schedCtrlRef);

/**
* @brief Enable or disable a schedule
*
Expand Down Expand Up @@ -128,6 +177,17 @@ Scheduler_enableWriteAccessToParameter(Scheduler self, const char* scheduleRef,
void
Scheduler_destroy(Scheduler self);

typedef struct sScheduleEvent* ScheduleEvent;

MmsValue*
ScheduleEvent_getValue(ScheduleEvent self);

uint64_t
ScheduleEvent_getTime(ScheduleEvent self);

void
ScheduleEvent_destroy(ScheduleEvent self);

#ifdef __cplusplus
}
#endif
Expand Down
29 changes: 29 additions & 0 deletions src/scheduler/der_scheduler_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,20 @@ struct sScheduler
void* targetValueHandlerParameter;
};

struct sScheduleEvent
{
uint64_t timestamp;
uint64_t lastStartTime;
MmsValue* value;
int priority;
};

ScheduleEvent
ScheduleEvent_create(uint64_t timestamp, MmsValue* value, int priority, uint64_t startTime);

void
ScheduleEvent_destroy(ScheduleEvent self);

void
scheduler_targetValueChanged(Scheduler self, ModelNode* targetAttr, MmsValue* value, Quality quality, uint64_t timestampMs);

Expand All @@ -132,6 +146,9 @@ ScheduleController_getScheduleReferenceWithIdx(ScheduleController self, int idx)
void
ScheduleController_setCtlEnt(ScheduleController self, const char* ctlEntValue);

const char*
ScheduleController_getCtlEntRef(ScheduleController self);

bool
ScheduleController_setSchdRef(ScheduleController self, const char* id, const char* ref);

Expand All @@ -147,6 +164,9 @@ scheduleController_scheduleValueUpdated(ScheduleController self, Schedule sched,
void
ScheduleController_initialize(ScheduleController self);

LinkedList
ScheduleController_createForecast(ScheduleController self, uint64_t startTime, uint64_t endTime);

Schedule
Schedule_create(LogicalNode* schedLn, IedServer server, IedModel* model);

Expand Down Expand Up @@ -204,6 +224,9 @@ scheduler_checkIfMultiObjInst(const char* name, const char* multiName);
Schedule
Scheduler_getScheduleByObjRef(Scheduler self, const char* objRef);

ScheduleController
Scheduler_getScheduleControllerByObjRef(Scheduler self, const char* objRef);

void
Schedule_setListeningController(Schedule self, ScheduleController controller);

Expand All @@ -222,6 +245,12 @@ Schedule_enableWriteAccessToStrTm(Schedule self, bool enable);
void
Schedule_enableWriteAccessToSchdReuse(Schedule self, bool enable);

ScheduleEvent
Schedule_getValueAt(Schedule self, uint64_t timestamp);

LinkedList
Schedule_runSchedule(Schedule self, uint64_t startTime, uint64_t endTime);

SchedulerStorage
SchedulerStorage_init(const char* databaseUri, int numberOfParameters, const char** parameters);

Expand Down
Loading