diff --git a/apps/aqhome-cgi/modules/devices/mdevices_vgraph.c b/apps/aqhome-cgi/modules/devices/mdevices_vgraph.c index fad25d3..ed3c0ae 100644 --- a/apps/aqhome-cgi/modules/devices/mdevices_vgraph.c +++ b/apps/aqhome-cgi/modules/devices/mdevices_vgraph.c @@ -53,6 +53,34 @@ enum { +/* ------------------------------------------------------------------------------------------------ + * vars + * ------------------------------------------------------------------------------------------------ + */ + +typedef struct MY_GRAPH_PARAMS MY_GRAPH_PARAMS; +struct MY_GRAPH_PARAMS { + const char *name; + const char *title; + const char *modifiers; + int startTimeDiff; + int acceptedAgeInSeconds; +}; + + + +static MY_GRAPH_PARAMS _graphParams[]={ + {"4h", "last 4 hours", "Lm5", 4*60*60, 2*60}, + {"1d", "last 24 hours", "Lm30", 24*60*60, 5*60}, + {"1w", "last 7 days", "Lm240", 7*24*60*60, 15*60}, + {"1m", "last 30 days", "Lm480", 30*24*60*60, 60*60}, + {"6m", "last 6 months", "Lm720", 182*24*60*60, 60*60}, + {"12m","last 12 months", "Lm1440", 365*24*60*60, 60*60}, + {NULL, NULL, NULL, 0, 0} +}; + + + /* ------------------------------------------------------------------------------------------------ * forward declarations * ------------------------------------------------------------------------------------------------ @@ -60,27 +88,22 @@ enum { static void _runGraphValueWithArgs(AQH_MODULE *m, AQCGI_REQUEST *rq, - AQH_SESSION *session, AQH_DATACLIENT *dc, const char *sDeviceName, const char *sValueName, GWEN_BUFFER *dbuf); static void _createGraph(AQH_DATACLIENT *dc, const AQH_VALUE *v, - int period, + const MY_GRAPH_PARAMS *graphParams, const char *graphTitle, int precision, const char *curveLabel, const char *sImgFile, int imgWidth, int imgHeight, uint64_t numDataPoints); static int _fileIsCurrent(const char *sPath, int seconds); -static AQDG_GRAPH *_mkGraphObjectWithTitle(const char *graphTitle, int period, int precision); -static int _getPeriodFromString(const char *sPeriod); -static int _getAcceptedAgeForPeriod(int period); -static void _mkPathForValueAndPeriod(AQH_MODULE *m, const AQH_VALUE *v, int pPeriod, GWEN_BUFFER *dbuf); -static uint64_t _getStartTimeForPeriod(int period); -static const char *_getModifiersForPeriod(int period); - +static AQDG_GRAPH *_mkGraphObjectWithTitle(const char *graphTitle, const MY_GRAPH_PARAMS *graphParams, int precision); +static void _mkPathForValueAndPeriod(AQH_MODULE *m, const AQH_VALUE *v, const MY_GRAPH_PARAMS *graphParams, GWEN_BUFFER *dbuf); static AQDG_GRAPH_DATAPAIR_LIST *_requestDataPairList(AQH_DATACLIENT *dc, const char *valueName, uint64_t tsBegin, uint64_t tsEnd, uint64_t num); static AQDG_GRAPH_DATAPAIR_LIST *_createDataPairListFromDataPoints(const uint64_t *dataPoints, uint64_t numValues); +static const MY_GRAPH_PARAMS *_getParamsByName(const char *s); @@ -95,11 +118,11 @@ void AQH_ModDevices_RunGraphValue(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION const char *sDeviceName; const char *sValueName; - DBG_ERROR(NULL, "GraphValue"); + DBG_DEBUG(NULL, "GraphValue"); dbQuery=AQCGI_Request_GetDbQuery(rq); sDeviceName=GWEN_DB_GetCharValue(dbQuery, "device", 0, NULL); sValueName=GWEN_DB_GetCharValue(dbQuery, "value", 0, NULL); - DBG_ERROR(NULL, "Device=%s, value=%s", sDeviceName?sDeviceName:"", sValueName?sValueName:""); + DBG_DEBUG(NULL, "Device=%s, value=%s", sDeviceName?sDeviceName:"", sValueName?sValueName:""); if (sDeviceName && *sDeviceName && sValueName && *sValueName) { GWEN_BUFFER *bufDeviceName; GWEN_BUFFER *bufValueName; @@ -108,7 +131,7 @@ void AQH_ModDevices_RunGraphValue(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION GWEN_Text_UnescapeToBufferTolerant(sDeviceName, bufDeviceName); bufValueName=GWEN_Buffer_new(0, 64, 0, 1); GWEN_Text_UnescapeToBufferTolerant(sValueName, bufValueName); - _runGraphValueWithArgs(m, rq, session, dc, + _runGraphValueWithArgs(m, rq, dc, GWEN_Buffer_GetStart(bufDeviceName), GWEN_Buffer_GetStart(bufValueName), dbuf); @@ -121,7 +144,6 @@ void AQH_ModDevices_RunGraphValue(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION void _runGraphValueWithArgs(AQH_MODULE *m, AQCGI_REQUEST *rq, - AQH_SESSION *session, AQH_DATACLIENT *dc, const char *sDeviceName, const char *sValueName, @@ -129,14 +151,16 @@ void _runGraphValueWithArgs(AQH_MODULE *m, { GWEN_DB_NODE *dbQuery; AQH_VALUE *value; + const MY_GRAPH_PARAMS *graphParams; const char *sPeriod; - int period; - DBG_ERROR(NULL, "GraphValue with args"); + DBG_DEBUG(NULL, "GraphValue with args"); dbQuery=AQCGI_Request_GetDbQuery(rq); sPeriod=GWEN_DB_GetCharValue(dbQuery, "period", 0, NULL); - period=sPeriod?_getPeriodFromString(sPeriod):VALUEGRAPH_PERIOD_1D; - DBG_ERROR(NULL, "Device=%s, value=%s, period=%s", + graphParams=_getParamsByName(sPeriod); + if (graphParams==NULL) + graphParams=&_graphParams[0]; + DBG_DEBUG(NULL, "Device=%s, value=%s, period=%s", sDeviceName?sDeviceName:"", sValueName?sValueName:"", sPeriod?sPeriod:""); @@ -146,12 +170,12 @@ void _runGraphValueWithArgs(AQH_MODULE *m, int rv; fbuf=GWEN_Buffer_new(0, 256, 0, 1); - _mkPathForValueAndPeriod(m, value, period, fbuf); - if (!_fileIsCurrent(GWEN_Buffer_GetStart(fbuf), _getAcceptedAgeForPeriod(period))) { - DBG_ERROR(NULL, "Creating graph"); + _mkPathForValueAndPeriod(m, value, graphParams, fbuf); + if (!_fileIsCurrent(GWEN_Buffer_GetStart(fbuf), graphParams->acceptedAgeInSeconds)) { + DBG_DEBUG(NULL, "Creating graph"); _createGraph(dc, value, - period, + graphParams, sValueName, 2, AQH_ValueModality_toString(AQH_Value_GetModality(value)), @@ -167,7 +191,7 @@ void _runGraphValueWithArgs(AQH_MODULE *m, // return file rv=GWEN_SyncIo_Helper_ReadFile(GWEN_Buffer_GetStart(fbuf), ibuf); if (rv<0) { - DBG_ERROR(NULL, "here (%d)", rv); + DBG_ERROR(NULL, "Error reading \"%s\" (%d)", GWEN_Buffer_GetStart(fbuf), rv); } else { GWEN_Buffer_Reset(dbuf); @@ -182,7 +206,7 @@ void _runGraphValueWithArgs(AQH_MODULE *m, AQH_Value_free(value); } else { - DBG_ERROR(NULL, "Could not get value"); + DBG_ERROR(NULL, "Could not get value \"%s/%s\"", sDeviceName, sValueName); } } @@ -199,7 +223,7 @@ int _fileIsCurrent(const char *sPath, int seconds) } t1=time(0); if ((t1-sb.st_mtime)<(time_t) seconds) { - DBG_ERROR(NULL, "File %s is current", sPath); + DBG_DEBUG(NULL, "File %s is current", sPath); return 1; } @@ -210,7 +234,7 @@ int _fileIsCurrent(const char *sPath, int seconds) void _createGraph(AQH_DATACLIENT *dc, const AQH_VALUE *v, - int period, + const MY_GRAPH_PARAMS *graphParams, const char *graphTitle, int precision, const char *curveLabel, const char *sImgFile, int imgWidth, int imgHeight, uint64_t numDataPoints) @@ -221,31 +245,27 @@ void _createGraph(AQH_DATACLIENT *dc, AQDG_OBJECT *graphObject; uint64_t tsBegin; uint64_t tsEnd; - const char *sModifier; AQDG_GRAPH_DATAPAIR_LIST *dpList; sValue=AQH_Value_GetNameForSystem(v); tsEnd=time(0); - tsBegin=_getStartTimeForPeriod(period); - g=_mkGraphObjectWithTitle(graphTitle, period, precision); - sModifier=_getModifiersForPeriod(period); + tsBegin=time(0)-(graphParams->startTimeDiff); + g=_mkGraphObjectWithTitle(graphTitle, graphParams, precision); - DBG_ERROR(NULL, "Requesting data for %s", sValue); dpList=_requestDataPairList(dc, sValue, tsBegin, tsEnd, numDataPoints); if (dpList) { - DBG_ERROR(NULL, "Adding data for %s", sValue); - AQDG_TimeGraph_ModifyDataAndAddCurve(g, curveLabel?curveLabel:sValue, sModifier, dpList); + DBG_DEBUG(NULL, "Adding data for %s", sValue); + AQDG_TimeGraph_ModifyDataAndAddCurve(g, curveLabel?curveLabel:sValue, graphParams->modifiers, dpList); } else { - DBG_ERROR(NULL, "No data"); + DBG_ERROR(NULL, "No data for %s", sValue); AQDG_Graph_free(g); return; } - DBG_ERROR(NULL, "Setup ticks for %s", sValue); AQDG_TimeGraph_SetupTicks(g, 0, 0.0, 0.0); - DBG_ERROR(NULL, "Draw graph for %s", sValue); + DBG_DEBUG(NULL, "Draw graph for %s", sValue); drawContext=AQDG_Draw_ContextCairo_Png_new(sImgFile, imgWidth, imgHeight); graphObject=AQDG_GraphWidget_new(NULL, AQDG_OBJECT_OPTIONS_STRETCHX | AQDG_OBJECT_OPTIONS_STRETCHY, drawContext); AQDG_Object_SetWidth(graphObject, imgWidth); @@ -261,25 +281,14 @@ void _createGraph(AQH_DATACLIENT *dc, -AQDG_GRAPH *_mkGraphObjectWithTitle(const char *graphTitle, int period, int precision) +AQDG_GRAPH *_mkGraphObjectWithTitle(const char *graphTitle, const MY_GRAPH_PARAMS *graphParams, int precision) { AQDG_GRAPH *g; GWEN_BUFFER *tbuf; - const char *s; tbuf=GWEN_Buffer_new(0, 256, 0, 1); - switch(period) { - case VALUEGRAPH_PERIOD_4H: s="last 4 hours"; break; - case VALUEGRAPH_PERIOD_1D: s="last 24 hours"; break; - case VALUEGRAPH_PERIOD_1W: s="last 7 days"; break; - case VALUEGRAPH_PERIOD_1M: s="last 30 days"; break; - case VALUEGRAPH_PERIOD_6M: s="last 6 months"; break; - case VALUEGRAPH_PERIOD_12M: s="last 12 months"; break; - default: s="last 24 hours"; break; - } - - GBAA(tbuf, "%s - %s", graphTitle, s); + GBAA(tbuf, "%s - %s", graphTitle, graphParams->title); g=AQDG_TimeGraph_new(GWEN_Buffer_GetStart(tbuf), NULL, "Value", NULL, precision); GWEN_Buffer_free(tbuf); @@ -287,26 +296,7 @@ AQDG_GRAPH *_mkGraphObjectWithTitle(const char *graphTitle, int period, int prec } -int _getPeriodFromString(const char *sPeriod) -{ - if (strcasecmp(sPeriod, "4h")==0) - return VALUEGRAPH_PERIOD_4H; - else if (strcasecmp(sPeriod, "1d")==0) - return VALUEGRAPH_PERIOD_1D; - else if (strcasecmp(sPeriod, "1w")==0) - return VALUEGRAPH_PERIOD_1W; - else if (strcasecmp(sPeriod, "1m")==0) - return VALUEGRAPH_PERIOD_1M; - else if (strcasecmp(sPeriod, "6m")==0) - return VALUEGRAPH_PERIOD_6M; - else if (strcasecmp(sPeriod, "12m")==0) - return VALUEGRAPH_PERIOD_12M; - return VALUEGRAPH_PERIOD_1D; -} - - - -void _mkPathForValueAndPeriod(AQH_MODULE *m, const AQH_VALUE *v, int period, GWEN_BUFFER *dbuf) +void _mkPathForValueAndPeriod(AQH_MODULE *m, const AQH_VALUE *v, const MY_GRAPH_PARAMS *graphParams, GWEN_BUFFER *dbuf) { AQH_SERVICE *sv; const char *s; @@ -321,75 +311,11 @@ void _mkPathForValueAndPeriod(AQH_MODULE *m, const AQH_VALUE *v, int period, GWE s=AQH_Value_GetNameForSystem(v); GWEN_Text_EscapeToBuffer(s, dbuf); - /* period */ - switch(period) { - case VALUEGRAPH_PERIOD_4H: s="4h"; break; - case VALUEGRAPH_PERIOD_1D: s="1d"; break; - case VALUEGRAPH_PERIOD_1W: s="1w"; break; - case VALUEGRAPH_PERIOD_1M: s="1m"; break; - case VALUEGRAPH_PERIOD_6M: s="6m"; break; - case VALUEGRAPH_PERIOD_12M: s="12m"; break; - default: s="1d"; break; - } - - GBAA(dbuf, "-%s.png", s); + GBAA(dbuf, "-%s.png", graphParams->name); } -uint64_t _getStartTimeForPeriod(int period) -{ - time_t t; - - t=time(0); - - /* period */ - switch(period) { - case VALUEGRAPH_PERIOD_4H: t-=4*60*60; break; - case VALUEGRAPH_PERIOD_1D: t-=24*60*60; break; - case VALUEGRAPH_PERIOD_1W: t-=7*24*60*60; break; - case VALUEGRAPH_PERIOD_1M: t-=30*24*60*60; break; - case VALUEGRAPH_PERIOD_6M: t-=182*24*60*60; break; - case VALUEGRAPH_PERIOD_12M: t-=365*24*60*60; break; - default: t-=24*60*60; break; - } - - return (uint64_t) t; -} - - - -const char *_getModifiersForPeriod(int period) -{ - /* period */ - switch(period) { - case VALUEGRAPH_PERIOD_4H: return "Lm5"; - case VALUEGRAPH_PERIOD_1D: return "Lm30"; - case VALUEGRAPH_PERIOD_1W: return "Lm240"; - case VALUEGRAPH_PERIOD_1M: return "Lm480"; - case VALUEGRAPH_PERIOD_6M: return "Lm720"; - case VALUEGRAPH_PERIOD_12M: return "Lm1440"; - default: return "Lm30"; - } -} - - - -int _getAcceptedAgeForPeriod(int period) -{ - /* period */ - switch(period) { - case VALUEGRAPH_PERIOD_4H: return 2*60; /* 2m */ - case VALUEGRAPH_PERIOD_1D: return 5*60; /* 5m */ - case VALUEGRAPH_PERIOD_1W: return 15*60; /* 15m */ - case VALUEGRAPH_PERIOD_1M: return 60*60; /* 1h */ - default: return 5*60; /* 5m */ - } -} - - - - AQDG_GRAPH_DATAPAIR_LIST *_requestDataPairList(AQH_DATACLIENT *dc, const char *valueName, uint64_t tsBegin, uint64_t tsEnd, uint64_t num) { @@ -407,7 +333,7 @@ AQDG_GRAPH_DATAPAIR_LIST *_requestDataPairList(AQH_DATACLIENT *dc, const char *v return dpList; } else { - DBG_ERROR(NULL, "No data received"); + DBG_ERROR(NULL, "No data received for %s", valueName); free(dataPoints); return NULL; } @@ -420,7 +346,7 @@ AQDG_GRAPH_DATAPAIR_LIST *_createDataPairListFromDataPoints(const uint64_t *data AQDG_GRAPH_DATAPAIR_LIST *dpList; uint64_t i; - DBG_ERROR(NULL, "Got %d datapoints", (int) numValues); + DBG_DEBUG(NULL, "Got %d datapoints", (int) numValues); dpList=AQDG_Graph_DataPair_List_new(); for(i=0; iname) { + if (strcasecmp(p->name, s)==0) + return p; + p++; + } + + return NULL; +}