/**************************************************************************** * This file is part of the project AqHome. * AqHome (c) by 2023 Martin Preuss, all rights reserved. * * The license for this file can be found in the file COPYING which you * should have received along with this file. ****************************************************************************/ #ifdef HAVE_CONFIG_H # include #endif #include "./u_values.h" #include "./u_objects.h" #include "./aqhomehttp.h" #include #include #include /* ------------------------------------------------------------------------------------------------ * defines * ------------------------------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------------------------------ * forward declarations * ------------------------------------------------------------------------------------------------ */ static int _addOrEditObject(AQH_HTTP_URLHANDLER *uh, GWEN_DB_NODE *db, int id); static GWEN_DB_NODE *_findObjectByIdAndReturnAsDb(AQH_HTTP_URLHANDLER *uh, int id); static int _writeAddPage(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq, GWEN_DB_NODE *dbValues, GWEN_BUFFER *pageBuf); static int _writeEditPage(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq, GWEN_DB_NODE *dbValues, GWEN_BUFFER *pageBuf); static void _listObjectsIntoBuffer(AQH_HTTP_URLHANDLER *uh, GWEN_BUFFER *pageBuf); static void _writeEditingTable(AQH_HTTP_URLHANDLER *uh, GWEN_DB_NODE *dbValues, GWEN_BUFFER *pageBuf); static void _setFromObject(AQH_VALUE *value, const AQH_VALUE *srcValue); /* ------------------------------------------------------------------------------------------------ * implementations * ------------------------------------------------------------------------------------------------ */ AQH_HTTP_URLHANDLER *AQH_ValuesHttpUrlHandler_new(AQH_SERVICE *sv) { AQH_HTTP_URLHANDLER *uh; uh=AQH_ObjectsHttpUrlHandler_new(sv, AQHOME_HTTP_PERMS_LIST_VALUES, AQHOME_HTTP_PERMS_ADD_VALUE, AQHOME_HTTP_PERMS_DEL_VALUE, AQHOME_HTTP_PERMS_EDIT_VALUE, "/values/list"); AQH_ObjectsHttpUrlHandler_SetAddOrEditObjectFn(uh, _addOrEditObject); AQH_ObjectsHttpUrlHandler_SetFindObjectByIdAndReturnAsDbFn(uh, _findObjectByIdAndReturnAsDb); AQH_ObjectsHttpUrlHandler_SetWriteAddPageFn(uh, _writeAddPage); AQH_ObjectsHttpUrlHandler_SetWriteEditPageFn(uh, _writeEditPage); AQH_ObjectsHttpUrlHandler_SetListObjectsIntoBufferFn(uh, _listObjectsIntoBuffer); return uh; } int _addOrEditObject(AQH_HTTP_URLHANDLER *uh, GWEN_DB_NODE *db, int id) { AQH_SERVICE *sv; AQH_STORAGE *sto; AQH_VALUE *newValue; const char *valueName; int rv; sv=AQH_HttpUrlHandler_GetHttpService(uh); sto=AqHomeHttpService_GetStorage(sv); newValue=AQH_Value_fromDb(db); valueName=AQH_Value_GetNameForSystem(newValue); if (!(valueName && *valueName)) { DBG_INFO(NULL, "Missing value name"); AQH_Value_free(newValue); return GWEN_ERROR_INVALID; } rv=AqHomeHttpService_LockStorage(sv); if (rv<0) { DBG_ERROR(NULL, "Error locking storage"); AQH_Value_free(newValue); return GWEN_ERROR_IO; } if (id>0) { AQH_VALUE *value; DBG_INFO(NULL, "Edit existing value"); value=AQH_Storage_GetValueById(sto, id); if (value==NULL) { AqHomeHttpService_UnlockStorage(sv); DBG_ERROR(NULL, "Value %d not found", id); AQH_Value_free(newValue); return GWEN_ERROR_NOT_FOUND; } AQH_Value_SetId(value, id); _setFromObject(value, newValue); AQH_Storage_AddRuntimeFlags(sto, AQH_STORAGE_RTFLAGS_MODIFIED); } else { AQH_VALUE *value; DBG_INFO(NULL, "Adding new value"); value=AQH_Storage_GetValueByName(sto, valueName); if (value) { AqHomeHttpService_UnlockStorage(sv); DBG_ERROR(NULL, "Value %s exists", valueName); AQH_Value_free(newValue); return GWEN_ERROR_FOUND; } value=AQH_Value_new(); AQH_Value_SetId(value, 0); _setFromObject(value, newValue); AQH_Storage_AddValue(sto, value); AQH_Storage_AddRuntimeFlags(sto, AQH_STORAGE_RTFLAGS_MODIFIED); } AQH_Value_free(newValue); rv=AqHomeHttpService_UnlockStorage(sv); if (rv<0) { DBG_ERROR(NULL, "Error unlocking storage"); return GWEN_ERROR_IO; } return 0; } void _setFromObject(AQH_VALUE *value, const AQH_VALUE *srcValue) { AQH_Value_SetName(value, AQH_Value_GetName(srcValue)); AQH_Value_SetTopicId(value, AQH_Value_GetTopicId(srcValue)); AQH_Value_SetValueType(value, AQH_Value_GetValueType(srcValue)); AQH_Value_SetValueUnits(value, AQH_Value_GetValueUnits(srcValue)); AQH_Value_SetDataPath(value, AQH_Value_GetDataPath(srcValue)); } GWEN_DB_NODE *_findObjectByIdAndReturnAsDb(AQH_HTTP_URLHANDLER *uh, int id) { AQH_SERVICE *sv; AQH_STORAGE *sto; const AQH_VALUE *value; sv=AQH_HttpUrlHandler_GetHttpService(uh); sto=AqHomeHttpService_GetStorage(sv); value=AQH_Storage_GetValueById(sto, id); if (value) { GWEN_DB_NODE *db; db=GWEN_DB_Group_new("value"); AQH_Value_toDb(value, db); return db; } return NULL; } int _writeAddPage(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq, GWEN_DB_NODE *dbValues, GWEN_BUFFER *pageBuf) { GWEN_Buffer_AppendArgs(pageBuf, "

%s


\n" "
", I18N("Add Value")); _writeEditingTable(uh, dbValues, pageBuf); GWEN_Buffer_AppendArgs(pageBuf, "
", I18N("Submit")); return 0; } int _writeEditPage(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq, GWEN_DB_NODE *dbValues, GWEN_BUFFER *pageBuf) { GWEN_Buffer_AppendArgs(pageBuf, "

%s


\n" "
", I18N("Edit Value"), (long unsigned int)(dbValues?GWEN_DB_GetIntValue(dbValues, "id", 0, 0):0)); _writeEditingTable(uh, dbValues, pageBuf); GWEN_Buffer_AppendArgs(pageBuf, "
", I18N("Submit")); return 0; } void _writeEditingTable(AQH_HTTP_URLHANDLER *uh, GWEN_DB_NODE *dbValues, GWEN_BUFFER *pageBuf) { AQH_SERVICE *sv; AQH_STORAGE *sto; const AQH_MQTT_TOPIC_LIST *topicList; unsigned long int selectedTopicId=0; char numbuf[16]; sv=AQH_HttpUrlHandler_GetHttpService(uh); sto=AqHomeHttpService_GetStorage(sv); topicList=AQH_Storage_GetMqttTopicList(sto); selectedTopicId=(unsigned long int)(dbValues?GWEN_DB_GetIntValue(dbValues, "TopicId", 0, 0):0); snprintf(numbuf, sizeof(numbuf)-1, "%lu", selectedTopicId); numbuf[sizeof(numbuf)-1]=0; GWEN_Buffer_AppendArgs(pageBuf, " " " " " " " " " ", I18N("Name"), dbValues?GWEN_DB_GetCharValue(dbValues, "name", 0, ""):""); GWEN_Buffer_AppendArgs(pageBuf, "" ""); GWEN_Buffer_AppendArgs(pageBuf, " " " " " " " ", I18N("Units"), dbValues?GWEN_DB_GetCharValue(dbValues, "valueUnits", 0, ""):""); GWEN_Buffer_AppendArgs(pageBuf, " " " " " " " " "
", I18N("Data Path (JSON)"), dbValues?GWEN_DB_GetCharValue(dbValues, "dataPath", 0, ""):""); } void _listObjectsIntoBuffer(AQH_HTTP_URLHANDLER *uh, GWEN_BUFFER *pageBuf) { AQH_SERVICE *sv; AQH_STORAGE *sto; const AQH_VALUE_LIST *rl; sv=AQH_HttpUrlHandler_GetHttpService(uh); sto=AqHomeHttpService_GetStorage(sv); GWEN_Buffer_AppendArgs(pageBuf, "

%s

" "" "" " " "", I18N("Values"), I18N("Name"), I18N("Topic"), I18N("Units"), I18N("Data Path")); GWEN_Buffer_AppendString(pageBuf, ""); rl=AQH_Storage_GetValueList(sto); if (rl) { const AQH_VALUE *value; value=AQH_Value_List_First(rl); while(value) { long unsigned int id; int topicId; const char *name; const char *topicName=NULL; const char *valueUnits; const char *dataPath; const AQH_MQTT_TOPIC *topic=NULL; id=(long unsigned int) AQH_Value_GetId(value); topicId=(long unsigned int) AQH_Value_GetTopicId(value); if (topicId>0) topic=AQH_Storage_GetMqttTopicById(sto, topicId); if (topic) topicName=AQH_MqttTopic_GetTopic(topic); name=AQH_Value_GetName(value); valueUnits=AQH_Value_GetValueUnits(value); dataPath=AQH_Value_GetDataPath(value); GWEN_Buffer_AppendArgs(pageBuf, "" "" "", name?name:"", topicName?topicName:"", valueUnits?valueUnits:"", dataPath?dataPath:"", id); value=AQH_Value_List_Next(value); } } GWEN_Buffer_AppendString(pageBuf, ""); GWEN_Buffer_AppendArgs(pageBuf, "
%s%s%s%s
%s%s%s%s" "
%s
", I18N("Add Value")); }