added urlhandler for devices.
This commit is contained in:
@@ -48,6 +48,7 @@
|
||||
u_objects.h
|
||||
u_objects_p.h
|
||||
u_rooms.h
|
||||
u_devices.h
|
||||
u_static.h
|
||||
u_static_p.h
|
||||
aqhomehttp.h
|
||||
@@ -68,6 +69,7 @@
|
||||
u_login.c
|
||||
u_objects.c
|
||||
u_rooms.c
|
||||
u_devices.c
|
||||
u_static.c
|
||||
main.c
|
||||
aqhomehttp.c
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "./aqhomehttp.h"
|
||||
#include "./u_login.h"
|
||||
#include "./u_rooms.h"
|
||||
#include "./u_devices.h"
|
||||
#include "./u_static.h"
|
||||
|
||||
#include "aqhome/msg/endpoint_tty.h"
|
||||
@@ -73,6 +74,7 @@ static GWEN_MSG_ENDPOINT *_acceptHttpFn(GWEN_MSG_ENDPOINT *ep, GWEN_SOCKET *sk,
|
||||
|
||||
static int _createUrlHandler_login(AQHOME_STORAGE *aqh);
|
||||
static int _createUrlHandler_rooms(AQHOME_STORAGE *aqh);
|
||||
static int _createUrlHandler_devices(AQHOME_STORAGE *aqh);
|
||||
static int _createUrlHandler_static(AQHOME_STORAGE *aqh);
|
||||
|
||||
|
||||
@@ -118,6 +120,12 @@ int AqHomeStorage_SetupHttp(AQHOME_STORAGE *aqh, GWEN_DB_NODE *dbArgs)
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv=_createUrlHandler_devices(aqh);
|
||||
if (rv<0) {
|
||||
DBG_INFO(NULL, "here (%d)", rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv=_createUrlHandler_static(aqh);
|
||||
if (rv<0) {
|
||||
DBG_INFO(NULL, "here (%d)", rv);
|
||||
@@ -249,6 +257,19 @@ int _createUrlHandler_rooms(AQHOME_STORAGE *aqh)
|
||||
|
||||
|
||||
|
||||
int _createUrlHandler_devices(AQHOME_STORAGE *aqh)
|
||||
{
|
||||
AQH_HTTP_URLHANDLER *uh;
|
||||
|
||||
uh=AQH_DevicesHttpUrlHandler_new(aqh->httpService);
|
||||
AQH_HttpUrlHandler_SetContentProvider(uh, AqHomeHttpService_GetContentTree(aqh->httpService));
|
||||
AQH_HttpUrlHandler_AddUrlPattern(uh, "/devices/*");
|
||||
AQH_HttpService_AddUrlHandler(aqh->httpService, uh);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int _createUrlHandler_static(AQHOME_STORAGE *aqh)
|
||||
{
|
||||
AQH_HTTP_URLHANDLER *uh;
|
||||
|
||||
338
apps/aqhome-storage/u_devices.c
Normal file
338
apps/aqhome-storage/u_devices.c
Normal file
@@ -0,0 +1,338 @@
|
||||
/****************************************************************************
|
||||
* 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 <config.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "./u_devices.h"
|
||||
#include "./u_objects.h"
|
||||
#include "./aqhomehttp.h"
|
||||
|
||||
#include <gwenhywfar/gwenhywfar.h>
|
||||
#include <gwenhywfar/debug.h>
|
||||
#include <gwenhywfar/i18n.h>
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* 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_DEVICE *device, const AQH_DEVICE *srcDevice);
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* implementations
|
||||
* ------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
AQH_HTTP_URLHANDLER *AQH_DevicesHttpUrlHandler_new(AQH_SERVICE *sv)
|
||||
{
|
||||
AQH_HTTP_URLHANDLER *uh;
|
||||
|
||||
uh=AQH_ObjectsHttpUrlHandler_new(sv,
|
||||
AQHOME_HTTP_PERMS_LIST_DEVICES,
|
||||
AQHOME_HTTP_PERMS_ADD_DEVICE,
|
||||
AQHOME_HTTP_PERMS_DEL_DEVICE,
|
||||
AQHOME_HTTP_PERMS_EDIT_DEVICE,
|
||||
"/devices/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_DEVICE *newDevice;
|
||||
const char *deviceName;
|
||||
int rv;
|
||||
|
||||
sv=AQH_HttpUrlHandler_GetHttpService(uh);
|
||||
sto=AqHomeHttpService_GetStorage(sv);
|
||||
|
||||
newDevice=AQH_Device_fromDb(db);
|
||||
|
||||
deviceName=AQH_Device_GetName(newDevice);
|
||||
if (!(deviceName && *deviceName)) {
|
||||
DBG_INFO(NULL, "Missing device name");
|
||||
AQH_Device_free(newDevice);
|
||||
return GWEN_ERROR_INVALID;
|
||||
}
|
||||
|
||||
rv=AqHomeHttpService_LockStorage(sv);
|
||||
if (rv<0) {
|
||||
DBG_ERROR(NULL, "Error locking storage");
|
||||
AQH_Device_free(newDevice);
|
||||
return GWEN_ERROR_IO;
|
||||
}
|
||||
|
||||
if (id>0) {
|
||||
AQH_DEVICE *device;
|
||||
|
||||
DBG_INFO(NULL, "Edit existing device");
|
||||
device=AQH_Storage_GetDeviceById(sto, id);
|
||||
if (device==NULL) {
|
||||
AqHomeHttpService_UnlockStorage(sv);
|
||||
DBG_ERROR(NULL, "Device %d not found", id);
|
||||
AQH_Device_free(newDevice);
|
||||
return GWEN_ERROR_NOT_FOUND;
|
||||
}
|
||||
AQH_Device_SetId(device, id);
|
||||
_setFromObject(device, newDevice);
|
||||
AQH_Storage_AddRuntimeFlags(sto, AQH_STORAGE_RTFLAGS_MODIFIED);
|
||||
}
|
||||
else {
|
||||
AQH_DEVICE *device;
|
||||
|
||||
DBG_INFO(NULL, "Adding new device");
|
||||
device=AQH_Storage_GetDeviceByName(sto, deviceName);
|
||||
if (device) {
|
||||
AqHomeHttpService_UnlockStorage(sv);
|
||||
DBG_ERROR(NULL, "Device %s exists", deviceName);
|
||||
AQH_Device_free(newDevice);
|
||||
return GWEN_ERROR_FOUND;
|
||||
}
|
||||
device=AQH_Device_new();
|
||||
AQH_Device_SetId(device, 0);
|
||||
_setFromObject(device, newDevice);
|
||||
AQH_Storage_AddDevice(sto, device);
|
||||
AQH_Storage_AddRuntimeFlags(sto, AQH_STORAGE_RTFLAGS_MODIFIED);
|
||||
}
|
||||
AQH_Device_free(newDevice);
|
||||
|
||||
rv=AqHomeHttpService_UnlockStorage(sv);
|
||||
if (rv<0) {
|
||||
DBG_ERROR(NULL, "Error unlocking storage");
|
||||
return GWEN_ERROR_IO;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _setFromObject(AQH_DEVICE *device, const AQH_DEVICE *srcDevice)
|
||||
{
|
||||
AQH_Device_SetRoomId(device, AQH_Device_GetRoomId(srcDevice));
|
||||
AQH_Device_SetName(device, AQH_Device_GetName(srcDevice));
|
||||
AQH_Device_SetLocation(device, AQH_Device_GetLocation(srcDevice));
|
||||
AQH_Device_SetDescription(device, AQH_Device_GetDescription(srcDevice));
|
||||
}
|
||||
|
||||
|
||||
|
||||
GWEN_DB_NODE *_findObjectByIdAndReturnAsDb(AQH_HTTP_URLHANDLER *uh, int id)
|
||||
{
|
||||
AQH_SERVICE *sv;
|
||||
AQH_STORAGE *sto;
|
||||
const AQH_DEVICE *device;
|
||||
|
||||
sv=AQH_HttpUrlHandler_GetHttpService(uh);
|
||||
sto=AqHomeHttpService_GetStorage(sv);
|
||||
|
||||
device=AQH_Storage_GetDeviceById(sto, id);
|
||||
if (device) {
|
||||
GWEN_DB_NODE *db;
|
||||
|
||||
db=GWEN_DB_Group_new("device");
|
||||
AQH_Device_toDb(device, 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,
|
||||
"<h2>%s</h2><br>\n"
|
||||
"<form action=\"/devices/add\" method=\"post\" enctype=\"application/x-www-form-urlencoded\">",
|
||||
I18N("Add Device"));
|
||||
_writeEditingTable(uh, dbValues, pageBuf);
|
||||
GWEN_Buffer_AppendArgs(pageBuf, "<input type=\"submit\" value=\"%s\"></form>", 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,
|
||||
"<h2>%s</h2><br>\n"
|
||||
"<form action=\"/devices/edit/%lu\" method=\"post\" enctype=\"application/x-www-form-urlencoded\">",
|
||||
I18N("Edit Device"),
|
||||
(long unsigned int)(dbValues?GWEN_DB_GetIntValue(dbValues, "id", 0, 0):0));
|
||||
_writeEditingTable(uh, dbValues, pageBuf);
|
||||
GWEN_Buffer_AppendArgs(pageBuf, "<input type=\"submit\" value=\"%s\"></form>", 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_ROOM_LIST *roomList;
|
||||
unsigned long int selectedRoomId=0;
|
||||
char numbuf[16];
|
||||
|
||||
sv=AQH_HttpUrlHandler_GetHttpService(uh);
|
||||
sto=AqHomeHttpService_GetStorage(sv);
|
||||
roomList=AQH_Storage_GetRoomList(sto);
|
||||
|
||||
selectedRoomId=(unsigned long int)(dbValues?GWEN_DB_GetIntValue(dbValues, "roomId", 0, 0):0);
|
||||
snprintf(numbuf, sizeof(numbuf)-1, "%lu", selectedRoomId);
|
||||
numbuf[sizeof(numbuf)-1]=0;
|
||||
|
||||
GWEN_Buffer_AppendArgs(pageBuf,
|
||||
" <table>"
|
||||
" <tr>"
|
||||
" <td><label for=\"name\">%s: </label></td>"
|
||||
" <td><input type=\"text\" name=\"name\" value=\"%s\" required></td>"
|
||||
" </tr>",
|
||||
I18N("Name"),
|
||||
dbValues?GWEN_DB_GetCharValue(dbValues, "name", 0, ""):"");
|
||||
GWEN_Buffer_AppendArgs(pageBuf,
|
||||
"<tr><td><label for=\"roomId\">%s: </label></td>"
|
||||
"<td><select id=\"roomId\" name=\"roomId\">",
|
||||
I18N("Room"));
|
||||
GWEN_Buffer_AppendArgs(pageBuf, "<option value=\"0\">%s</option>", I18N("-- select room --"));
|
||||
|
||||
if (roomList) {
|
||||
const AQH_ROOM *r;
|
||||
|
||||
r=AQH_Room_List_First(roomList);
|
||||
while(r) {
|
||||
const char *roomName;
|
||||
|
||||
roomName=AQH_Room_GetName(r);
|
||||
if (roomName && *roomName) {
|
||||
snprintf(numbuf, sizeof(numbuf)-1, "%lu", (unsigned long int) AQH_Room_GetId(r));
|
||||
numbuf[sizeof(numbuf)-1]=0;
|
||||
if (selectedRoomId && AQH_Room_GetId(r)==selectedRoomId)
|
||||
GWEN_Buffer_AppendArgs(pageBuf, "<option value=\"%s\" selected>%s</option>", numbuf, roomName);
|
||||
else
|
||||
GWEN_Buffer_AppendArgs(pageBuf, "<option value=\"%s\">%s</option>", numbuf, roomName);
|
||||
}
|
||||
r=AQH_Room_List_Next(r);
|
||||
}
|
||||
}
|
||||
GWEN_Buffer_AppendString(pageBuf, "</select></td></tr>");
|
||||
|
||||
GWEN_Buffer_AppendArgs(pageBuf,
|
||||
" <tr>"
|
||||
" <td><label for=\"location\">%s: </label></td>"
|
||||
" <td><input type=\"text\" name=\"location\" value=\"%s\" required></td>"
|
||||
" </tr>"
|
||||
" <tr>"
|
||||
" <td><label for=\"description\">%s: </label></td>"
|
||||
" <td><input type=\"text\" name=\"description\" value=\"%s\" ></td>"
|
||||
" </tr>"
|
||||
" </table>",
|
||||
I18N("Location"),
|
||||
dbValues?GWEN_DB_GetCharValue(dbValues, "location", 0, ""):"",
|
||||
I18N("Description"),
|
||||
dbValues?GWEN_DB_GetCharValue(dbValues, "description", 0, ""):"");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _listObjectsIntoBuffer(AQH_HTTP_URLHANDLER *uh, GWEN_BUFFER *pageBuf)
|
||||
{
|
||||
AQH_SERVICE *sv;
|
||||
AQH_STORAGE *sto;
|
||||
const AQH_DEVICE_LIST *rl;
|
||||
|
||||
sv=AQH_HttpUrlHandler_GetHttpService(uh);
|
||||
sto=AqHomeHttpService_GetStorage(sv);
|
||||
|
||||
GWEN_Buffer_AppendArgs(pageBuf,
|
||||
"<h2>%s</h2>"
|
||||
"<table class=\"dataTable\">"
|
||||
"<thead>"
|
||||
" <tr><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th></th></tr>"
|
||||
"</thead>",
|
||||
I18N("Devices"),
|
||||
I18N("Name"),
|
||||
I18N("Room"),
|
||||
I18N("Location"),
|
||||
I18N("Description"));
|
||||
GWEN_Buffer_AppendString(pageBuf, "<tbody>");
|
||||
rl=AQH_Storage_GetDeviceList(sto);
|
||||
if (rl) {
|
||||
const AQH_DEVICE *device;
|
||||
|
||||
device=AQH_Device_List_First(rl);
|
||||
while(device) {
|
||||
long unsigned int id;
|
||||
int roomId;
|
||||
const char *name;
|
||||
const char *roomName=NULL;
|
||||
const char *descr;
|
||||
const char *location;
|
||||
const AQH_ROOM *r=NULL;
|
||||
|
||||
id=(long unsigned int) AQH_Device_GetId(device);
|
||||
roomId=(long unsigned int) AQH_Device_GetRoomId(device);
|
||||
if (roomId>0)
|
||||
r=AQH_Storage_GetRoomById(sto, roomId);
|
||||
if (r)
|
||||
roomName=AQH_Room_GetName(r);
|
||||
|
||||
name=AQH_Device_GetName(device);
|
||||
descr=AQH_Device_GetDescription(device);
|
||||
location=AQH_Device_GetLocation(device);
|
||||
GWEN_Buffer_AppendArgs(pageBuf,
|
||||
"<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td>"
|
||||
"<td><a href=\"/devices/edit/%lu\">"
|
||||
"<IMG src=\"/pics/edit.png\" width=32 height=32 align=left border=0></a></td>"
|
||||
"</tr>",
|
||||
name?name:"",
|
||||
roomName?roomName:"",
|
||||
location?location:"",
|
||||
descr?descr:"", id);
|
||||
|
||||
device=AQH_Device_List_Next(device);
|
||||
}
|
||||
}
|
||||
GWEN_Buffer_AppendString(pageBuf, "</tbody>");
|
||||
GWEN_Buffer_AppendArgs(pageBuf, "</table><a href=\"/devices/add\">%s</a><br>", I18N("Add Device"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
23
apps/aqhome-storage/u_devices.h
Normal file
23
apps/aqhome-storage/u_devices.h
Normal file
@@ -0,0 +1,23 @@
|
||||
/****************************************************************************
|
||||
* 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.
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef AQHOME_STORAGE_U_DEVICES_H
|
||||
#define AQHOME_STORAGE_U_DEVICES_H
|
||||
|
||||
|
||||
#include "aqhome/http/urlhandler.h"
|
||||
|
||||
|
||||
|
||||
AQH_HTTP_URLHANDLER *AQH_DevicesHttpUrlHandler_new(AQH_SERVICE *sv);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -48,21 +48,21 @@
|
||||
<default>0</default>
|
||||
<preset>0</preset>
|
||||
<access>public</access>
|
||||
<flags></flags>
|
||||
<flags>own with_getbymember</flags>
|
||||
</member>
|
||||
|
||||
<member name="location" type="char_ptr" maxlen="32">
|
||||
<default>0</default>
|
||||
<preset>0</preset>
|
||||
<access>public</access>
|
||||
<flags></flags>
|
||||
<flags>own</flags>
|
||||
</member>
|
||||
|
||||
<member name="description" type="char_ptr" maxlen="256">
|
||||
<default>0</default>
|
||||
<preset>0</preset>
|
||||
<access>public</access>
|
||||
<flags></flags>
|
||||
<flags>own</flags>
|
||||
</member>
|
||||
|
||||
</members>
|
||||
|
||||
@@ -143,6 +143,13 @@ AQH_DEVICE *AQH_Storage_GetDeviceById(const AQH_STORAGE *sto, uint64_t id)
|
||||
|
||||
|
||||
|
||||
AQH_DEVICE *AQH_Storage_GetDeviceByName(const AQH_STORAGE *sto, const char *s)
|
||||
{
|
||||
return sto?AQH_Device_List_GetByName(sto->deviceList, s):NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AQH_Storage_AddMqttTopic(AQH_STORAGE *sto, AQH_MQTT_TOPIC *t)
|
||||
{
|
||||
if (sto && t) {
|
||||
|
||||
@@ -57,6 +57,7 @@ AQHOME_API AQH_ROOM *AQH_Storage_GetRoomByName(const AQH_STORAGE *sto, const cha
|
||||
AQHOME_API void AQH_Storage_AddDevice(AQH_STORAGE *sto, AQH_DEVICE *dev);
|
||||
AQHOME_API AQH_DEVICE_LIST *AQH_Storage_GetDeviceList(const AQH_STORAGE *sto);
|
||||
AQHOME_API AQH_DEVICE *AQH_Storage_GetDeviceById(const AQH_STORAGE *sto, uint64_t id);
|
||||
AQHOME_API AQH_DEVICE *AQH_Storage_GetDeviceByName(const AQH_STORAGE *sto, const char *s);
|
||||
|
||||
AQHOME_API void AQH_Storage_AddMqttTopic(AQH_STORAGE *sto, AQH_MQTT_TOPIC *t);
|
||||
AQHOME_API AQH_MQTT_TOPIC_LIST *AQH_Storage_GetMqttTopicList(const AQH_STORAGE *sto);
|
||||
|
||||
Reference in New Issue
Block a user