aqhome-react: fixed timeprogram module.
This commit is contained in:
@@ -29,6 +29,10 @@
|
|||||||
|
|
||||||
#define AQHOMEREACT_UNIT_TIMEPROGRAM_OUTSLOT_OUTPUT 0
|
#define AQHOMEREACT_UNIT_TIMEPROGRAM_OUTSLOT_OUTPUT 0
|
||||||
|
|
||||||
|
#define AQHOMEREACT_UNIT_TIMEPROGRAM_CREATEINTERVAL_MIN 60 /* 1h */
|
||||||
|
#define AQHOMEREACT_UNIT_TIMEPROGRAM_CREATEINTERVAL_SEC (61*60) /* 61m */
|
||||||
|
|
||||||
|
#define AQHOMEREACT_UNIT_TIMEPROGRAM_CHECKINTERVAL_SEC 60 /* 1m */
|
||||||
|
|
||||||
GWEN_INHERIT(AQHREACT_UNIT, AQHREACT_UNIT_TIMEPROGRAM);
|
GWEN_INHERIT(AQHREACT_UNIT, AQHREACT_UNIT_TIMEPROGRAM);
|
||||||
|
|
||||||
@@ -39,19 +43,17 @@ GWEN_INHERIT(AQHREACT_UNIT, AQHREACT_UNIT_TIMEPROGRAM);
|
|||||||
* ------------------------------------------------------------------------------------------------
|
* ------------------------------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static MODULE_TIMER_ACTION *ModuleTimerAction_new(int hourTime, double value);
|
static MODULE_TIMER_ACTION *ModuleTimerAction_new(int64_t triggerTime, double value);
|
||||||
static void ModuleTimerAction_free(MODULE_TIMER_ACTION *act);
|
static void ModuleTimerAction_free(MODULE_TIMER_ACTION *act);
|
||||||
|
|
||||||
static void GWENHYWFAR_CB _freeData(void *bp, void *p);
|
static void GWENHYWFAR_CB _freeData(void *bp, void *p);
|
||||||
static int _cbProcess(AQHREACT_UNIT *unit);
|
static int _cbProcess(AQHREACT_UNIT *unit);
|
||||||
static int _readRules(AQHREACT_UNIT *unit);
|
static int _readRules(AQHREACT_UNIT *unit);
|
||||||
|
|
||||||
static int _handleActionsForGivenTime(AQHREACT_UNIT *unit, int hourMins);
|
static int _checkAndAddActions(AQHREACT_UNIT *unit, AQHREACT_UNIT_TIMEPROGRAM *xunit);
|
||||||
static int _checkAndAddActions(AQHREACT_UNIT *unit);
|
static int _addActionsForNextMinutes(GWEN_TIMESTAMP *ts, int minutes,
|
||||||
static int _addActionsForGivenTime(const GWEN_TIME *ti,
|
const AQHREACT_PRGRULE_LIST *ruleList, MODULE_TIMER_ACTION_LIST *actionList);
|
||||||
int hour,
|
static int _handlePendingActions(AQHREACT_UNIT *unit, AQHREACT_UNIT_TIMEPROGRAM *xunit);
|
||||||
const AQHREACT_PRGRULE_LIST *ruleList,
|
|
||||||
MODULE_TIMER_ACTION_LIST *actionList);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -68,14 +70,14 @@ GWEN_LIST_FUNCTIONS(MODULE_TIMER_ACTION, ModuleTimerAction);
|
|||||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
*/
|
*/
|
||||||
|
|
||||||
MODULE_TIMER_ACTION *ModuleTimerAction_new(int hourTime, double value)
|
MODULE_TIMER_ACTION *ModuleTimerAction_new(int64_t triggerTime, double value)
|
||||||
{
|
{
|
||||||
MODULE_TIMER_ACTION *act;
|
MODULE_TIMER_ACTION *act;
|
||||||
|
|
||||||
GWEN_NEW_OBJECT(MODULE_TIMER_ACTION, act);
|
GWEN_NEW_OBJECT(MODULE_TIMER_ACTION, act);
|
||||||
GWEN_LIST_INIT(MODULE_TIMER_ACTION, act);
|
GWEN_LIST_INIT(MODULE_TIMER_ACTION, act);
|
||||||
|
|
||||||
act->hourMinutes=hourTime;
|
act->triggerTime=triggerTime;
|
||||||
act->value=value;
|
act->value=value;
|
||||||
|
|
||||||
return act;
|
return act;
|
||||||
@@ -112,6 +114,7 @@ AQHREACT_UNIT *AqHomeReact_UnitTimeProgram_new(AQH_OBJECT *aqh)
|
|||||||
GWEN_INHERIT_SETDATA(AQHREACT_UNIT, AQHREACT_UNIT_TIMEPROGRAM, unit, xunit, _freeData);
|
GWEN_INHERIT_SETDATA(AQHREACT_UNIT, AQHREACT_UNIT_TIMEPROGRAM, unit, xunit, _freeData);
|
||||||
|
|
||||||
xunit->actionList=ModuleTimerAction_List_new();
|
xunit->actionList=ModuleTimerAction_List_new();
|
||||||
|
xunit->lastActionHour=-1;
|
||||||
AQHREACT_Unit_SetProcessFn(unit, _cbProcess);
|
AQHREACT_Unit_SetProcessFn(unit, _cbProcess);
|
||||||
|
|
||||||
port=AQHREACT_Port_new();
|
port=AQHREACT_Port_new();
|
||||||
@@ -125,6 +128,8 @@ AQHREACT_UNIT *AqHomeReact_UnitTimeProgram_new(AQH_OBJECT *aqh)
|
|||||||
AQHREACT_Param_SetDataType(param, AQHREACT_DATAOBJECTTYPE_STRING);
|
AQHREACT_Param_SetDataType(param, AQHREACT_DATAOBJECTTYPE_STRING);
|
||||||
AQHREACT_Unit_AddParam(unit, param);
|
AQHREACT_Unit_AddParam(unit, param);
|
||||||
|
|
||||||
|
xunit->nextAddTime=GWEN_Timestamp_NowInLocalTime();
|
||||||
|
|
||||||
return unit;
|
return unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,6 +143,7 @@ void GWENHYWFAR_CB _freeData(GWEN_UNUSED void *bp, void *p)
|
|||||||
|
|
||||||
ModuleTimerAction_List_free(xunit->actionList);
|
ModuleTimerAction_List_free(xunit->actionList);
|
||||||
AQHREACT_PrgRule_List_free(xunit->ruleList);
|
AQHREACT_PrgRule_List_free(xunit->ruleList);
|
||||||
|
GWEN_Timestamp_free(xunit->nextAddTime);
|
||||||
GWEN_FREE_OBJECT(xunit);
|
GWEN_FREE_OBJECT(xunit);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,6 +161,7 @@ int _cbProcess(AQHREACT_UNIT *unit)
|
|||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
if (xunit->ruleList==NULL) {
|
if (xunit->ruleList==NULL) {
|
||||||
|
DBG_INFO(NULL, "Reading rules");
|
||||||
rv=_readRules(unit);
|
rv=_readRules(unit);
|
||||||
if (rv<0) {
|
if (rv<0) {
|
||||||
DBG_INFO(NULL, "here (%d)", rv);
|
DBG_INFO(NULL, "here (%d)", rv);
|
||||||
@@ -163,7 +170,7 @@ int _cbProcess(AQHREACT_UNIT *unit)
|
|||||||
didSomething=1;
|
didSomething=1;
|
||||||
}
|
}
|
||||||
|
|
||||||
rv=_checkAndAddActions(unit);
|
rv=_checkAndAddActions(unit, xunit);
|
||||||
if (rv<0) {
|
if (rv<0) {
|
||||||
DBG_INFO(NULL, "here (%d)", rv);
|
DBG_INFO(NULL, "here (%d)", rv);
|
||||||
return rv;
|
return rv;
|
||||||
@@ -177,58 +184,40 @@ int _cbProcess(AQHREACT_UNIT *unit)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _checkAndAddActions(AQHREACT_UNIT *unit)
|
int _checkAndAddActions(AQHREACT_UNIT *unit, AQHREACT_UNIT_TIMEPROGRAM *xunit)
|
||||||
{
|
{
|
||||||
AQHREACT_UNIT_TIMEPROGRAM *xunit;
|
|
||||||
GWEN_TIME *ti;
|
|
||||||
int didSomething=0;
|
int didSomething=0;
|
||||||
|
|
||||||
xunit=GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_TIMEPROGRAM, unit);
|
xunit=GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_TIMEPROGRAM, unit);
|
||||||
ti=GWEN_CurrentTime();
|
if (xunit) {
|
||||||
if (ti) {
|
time_t now;
|
||||||
int hours;
|
|
||||||
int mins;
|
|
||||||
int secs;
|
|
||||||
int hourMins;
|
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
/* translate current time */
|
now=time(NULL);
|
||||||
rv=GWEN_Time_GetBrokenDownTime(ti, &hours, &mins, &secs);
|
if (now-xunit->lastCreateTime>AQHOMEREACT_UNIT_TIMEPROGRAM_CREATEINTERVAL_SEC) {
|
||||||
if (rv<0) {
|
rv=_addActionsForNextMinutes(xunit->nextAddTime,
|
||||||
DBG_INFO(NULL, "here (%d)", rv);
|
AQHOMEREACT_UNIT_TIMEPROGRAM_CREATEINTERVAL_MIN,
|
||||||
GWEN_Time_free(ti);
|
xunit->ruleList,
|
||||||
return rv;
|
xunit->actionList);
|
||||||
}
|
if (rv<0) {
|
||||||
hourMins=(hours*60)+mins;
|
DBG_INFO(NULL, "here (%d)", rv);
|
||||||
|
return rv;
|
||||||
rv=GWEN_Time_AddSeconds(ti, 60*60); /* next hour */
|
}
|
||||||
if (rv<0) {
|
if (rv>0)
|
||||||
DBG_INFO(NULL, "here (%d)", rv);
|
didSomething=1;
|
||||||
GWEN_Time_free(ti);
|
xunit->lastCreateTime=now;
|
||||||
return rv;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rv=GWEN_Time_GetBrokenDownTime(ti, &hours, &mins, &secs);
|
if (now-xunit->lastCheckTime>AQHOMEREACT_UNIT_TIMEPROGRAM_CHECKINTERVAL_SEC) {
|
||||||
if (rv<0) {
|
rv=_handlePendingActions(unit, xunit);
|
||||||
DBG_INFO(NULL, "here (%d)", rv);
|
if (rv<0) {
|
||||||
GWEN_Time_free(ti);
|
DBG_INFO(NULL, "here (%d)", rv);
|
||||||
return rv;
|
return rv;
|
||||||
|
}
|
||||||
|
if (rv>0)
|
||||||
|
didSomething=1;
|
||||||
|
xunit->lastCheckTime=now;
|
||||||
}
|
}
|
||||||
if (hours!=xunit->lastActionHour) {
|
|
||||||
DBG_INFO(NULL, "Adding actions for next hour %02d", hours);
|
|
||||||
_addActionsForGivenTime(ti, hours, xunit->ruleList, xunit->actionList);
|
|
||||||
xunit->lastActionHour=hours;
|
|
||||||
didSomething=1;
|
|
||||||
}
|
|
||||||
GWEN_Time_free(ti);
|
|
||||||
|
|
||||||
rv=_handleActionsForGivenTime(unit, hourMins);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_INFO(NULL, "here (%d)", rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
if (rv>0)
|
|
||||||
didSomething=1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return didSomething?1:0;
|
return didSomething?1:0;
|
||||||
@@ -236,64 +225,78 @@ int _checkAndAddActions(AQHREACT_UNIT *unit)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _handleActionsForGivenTime(AQHREACT_UNIT *unit, int hourMins)
|
int _handlePendingActions(AQHREACT_UNIT *unit, AQHREACT_UNIT_TIMEPROGRAM *xunit)
|
||||||
{
|
{
|
||||||
AQHREACT_UNIT_TIMEPROGRAM *xunit;
|
|
||||||
MODULE_TIMER_ACTION *action;
|
|
||||||
int valueSent=0;
|
int valueSent=0;
|
||||||
|
|
||||||
xunit=GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_TIMEPROGRAM, unit);
|
if (unit && xunit) {
|
||||||
action=ModuleTimerAction_List_First(xunit->actionList);
|
AQHREACT_PORT *outputPort;
|
||||||
while(action) {
|
|
||||||
MODULE_TIMER_ACTION *nextAction;
|
|
||||||
|
|
||||||
nextAction=ModuleTimerAction_List_Next(action);
|
outputPort=AQHREACT_Unit_GetOutputPortByIdForUnit(unit, AQHOMEREACT_UNIT_TIMEPROGRAM_OUTSLOT_OUTPUT);
|
||||||
if ((hourMins>action->hourMinutes) || (hourMins+(23*60))<action->hourMinutes) {
|
if (outputPort) {
|
||||||
ModuleTimerAction_List_Del(action);
|
GWEN_TIMESTAMP *ts;
|
||||||
DBG_INFO(NULL, "Sending output value %.2f", action->value);
|
int64_t nowInt64;
|
||||||
AQHREACT_Unit_OutputDoubleData(unit, AQHOMEREACT_UNIT_TIMEPROGRAM_OUTSLOT_OUTPUT, action->value);
|
MODULE_TIMER_ACTION *action;
|
||||||
ModuleTimerAction_free(action);
|
|
||||||
valueSent=1;
|
ts=GWEN_Timestamp_NowInLocalTime();
|
||||||
|
nowInt64=ts?GWEN_Timestamp_toInt64(ts):0;
|
||||||
|
GWEN_Timestamp_free(ts);
|
||||||
|
|
||||||
|
xunit=GWEN_INHERIT_GETDATA(AQHREACT_UNIT, AQHREACT_UNIT_TIMEPROGRAM, unit);
|
||||||
|
action=ModuleTimerAction_List_First(xunit->actionList);
|
||||||
|
while(action) {
|
||||||
|
MODULE_TIMER_ACTION *nextAction;
|
||||||
|
|
||||||
|
nextAction=ModuleTimerAction_List_Next(action);
|
||||||
|
if (action->triggerTime<nowInt64) {
|
||||||
|
ModuleTimerAction_List_Del(action);
|
||||||
|
DBG_INFO(NULL, "Sending output value %.2f", action->value);
|
||||||
|
AQHREACT_Unit_OutputDoubleData(unit, outputPort, action->value);
|
||||||
|
ModuleTimerAction_free(action);
|
||||||
|
valueSent=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
action=nextAction;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
action=nextAction;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return valueSent?1:0;
|
return valueSent?1:0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _addActionsForGivenTime(const GWEN_TIME *ti, int hour, const AQHREACT_PRGRULE_LIST *ruleList, MODULE_TIMER_ACTION_LIST *actionList)
|
int _addActionsForNextMinutes(GWEN_TIMESTAMP *ts, int minutes, const AQHREACT_PRGRULE_LIST *ruleList, MODULE_TIMER_ACTION_LIST *actionList)
|
||||||
{
|
{
|
||||||
int actionsAdded=0;
|
int actionsAdded=0;
|
||||||
GWEN_DATE *dt;
|
int i;
|
||||||
int dayOfMonth;
|
|
||||||
int month;
|
|
||||||
int dayOfWeek;
|
|
||||||
int mins;
|
|
||||||
|
|
||||||
dt=GWEN_Date_fromTime(ti);
|
for (i=0; i<minutes; i++) {
|
||||||
month=GWEN_Date_GetMonth(dt);
|
|
||||||
dayOfMonth=GWEN_Date_GetDay(dt);
|
|
||||||
dayOfWeek=GWEN_Date_WeekDay(dt);
|
|
||||||
GWEN_Date_free(dt);
|
|
||||||
|
|
||||||
for (mins=0; mins<60; mins++) {
|
|
||||||
const AQHREACT_PRGRULE *rule;
|
const AQHREACT_PRGRULE *rule;
|
||||||
|
int64_t triggerTime;
|
||||||
|
|
||||||
|
triggerTime=GWEN_Timestamp_toInt64(ts);
|
||||||
|
|
||||||
rule=AQHREACT_PrgRule_List_First(ruleList);
|
rule=AQHREACT_PrgRule_List_First(ruleList);
|
||||||
while(rule) {
|
while(rule) {
|
||||||
if (AQHREACT_PrgRule_Matches(rule, mins, hour, dayOfMonth, month, dayOfWeek)>0) {
|
if (AQHREACT_PrgRule_Matches(rule,
|
||||||
|
GWEN_Timestamp_GetMinute(ts),
|
||||||
|
GWEN_Timestamp_GetHour(ts),
|
||||||
|
GWEN_Timestamp_GetDay(ts),
|
||||||
|
GWEN_Timestamp_GetMonth(ts),
|
||||||
|
GWEN_Timestamp_GetWeekDay(ts))>0) {
|
||||||
MODULE_TIMER_ACTION *act;
|
MODULE_TIMER_ACTION *act;
|
||||||
|
|
||||||
act=ModuleTimerAction_new((hour*60)+mins, AQHREACT_PrgRule_GetValue(rule));
|
DBG_INFO(NULL, "- rule matches for %s, creating action", GWEN_Timestamp_GetString(ts));
|
||||||
|
act=ModuleTimerAction_new(triggerTime, AQHREACT_PrgRule_GetValue(rule));
|
||||||
ModuleTimerAction_List_Add(act, actionList);
|
ModuleTimerAction_List_Add(act, actionList);
|
||||||
actionsAdded=1;
|
actionsAdded=1;
|
||||||
}
|
}
|
||||||
rule=AQHREACT_PrgRule_List_Next(rule);
|
rule=AQHREACT_PrgRule_List_Next(rule);
|
||||||
}
|
} /* while */
|
||||||
}
|
|
||||||
|
GWEN_Timestamp_AddSeconds(ts, 60); /* next min */
|
||||||
|
} /* for */
|
||||||
|
|
||||||
return actionsAdded?1:0;
|
return actionsAdded?1:0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,10 @@
|
|||||||
#include "aqhome-react/types/prgrule.h"
|
#include "aqhome-react/types/prgrule.h"
|
||||||
|
|
||||||
#include <gwenhywfar/list.h>
|
#include <gwenhywfar/list.h>
|
||||||
|
#include <gwenhywfar/timestamp.h>
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -29,7 +33,7 @@ GWEN_LIST_FUNCTION_DEFS(MODULE_TIMER_ACTION, ModuleTimerAction)
|
|||||||
struct MODULE_TIMER_ACTION {
|
struct MODULE_TIMER_ACTION {
|
||||||
GWEN_LIST_ELEMENT(MODULE_TIMER_ACTION)
|
GWEN_LIST_ELEMENT(MODULE_TIMER_ACTION)
|
||||||
|
|
||||||
int hourMinutes;
|
int64_t triggerTime;
|
||||||
double value;
|
double value;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -40,6 +44,10 @@ struct AQHREACT_UNIT_TIMEPROGRAM {
|
|||||||
MODULE_TIMER_ACTION_LIST *actionList;
|
MODULE_TIMER_ACTION_LIST *actionList;
|
||||||
|
|
||||||
int lastActionHour;
|
int lastActionHour;
|
||||||
|
GWEN_TIMESTAMP *nextAddTime;
|
||||||
|
time_t lastCheckTime;
|
||||||
|
time_t lastCreateTime;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user