Improved mqttlog daemaon: persistent registered devices.
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
#include <gwenhywfar/endpoint_multilayer.h>
|
||||
#include <gwenhywfar/text.h>
|
||||
#include <gwenhywfar/xml.h>
|
||||
#include <gwenhywfar/directory.h>
|
||||
#include <gwenhywfar/debug.h>
|
||||
|
||||
|
||||
@@ -41,7 +42,8 @@
|
||||
*/
|
||||
|
||||
static AQHMQTT_DEVICE_LIST *_readDeviceFiles(AQHOME_MQTT *aqh, const GWEN_STRINGLIST *sl);
|
||||
static AQHMQTT_DEVICE *_readDeviceFile(AQHOME_MQTT *aqh, const char *sFilename);
|
||||
static int _readDeviceFileToList(AQHOME_MQTT *aqh, const char *sFilename, AQHMQTT_DEVICE_LIST *deviceList);
|
||||
static int _readXmlDevices(AQHOME_MQTT *aqh, GWEN_XMLNODE *deviceListNode, AQHMQTT_DEVICE_LIST *deviceList);
|
||||
static AQHMQTT_DEVICE *_readXmlDevice(AQHOME_MQTT *aqh, GWEN_XMLNODE *deviceNode);
|
||||
static AQHMQTT_TOPIC_LIST *_readXmlTopicList(AQHOME_MQTT *aqh, GWEN_XMLNODE *parentNode);
|
||||
static AQHMQTT_TOPIC *_readXmlTopic(AQHOME_MQTT *aqh, GWEN_XMLNODE *topicNode);
|
||||
@@ -58,27 +60,32 @@ static AQHMQTT_TRANSLATION *_readXmlTranslation(AQHOME_MQTT *aqh, GWEN_XMLNODE *
|
||||
* ------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
AQHMQTT_DEVICE_LIST *AqHomeMqttLog_ReadRuntimeDataDeviceFiles(AQHOME_MQTT *aqh)
|
||||
AQHMQTT_DEVICE_LIST *AqHomeMqttLog_ReadDeviceFile(AQHOME_MQTT *aqh, const char *sFilename)
|
||||
{
|
||||
GWEN_STRINGLIST *sl;
|
||||
int rv;
|
||||
|
||||
sl=AQH_GetListOfMatchingRuntimeDataFiles("aqhome/devices", "*.xml");
|
||||
if (sl) {
|
||||
rv=GWEN_Directory_GetPath(sFilename, GWEN_PATH_FLAGS_CHECKROOT | GWEN_PATH_FLAGS_PATHMUSTEXIST | GWEN_PATH_FLAGS_VARIABLE);
|
||||
if (rv<0) {
|
||||
DBG_ERROR(NULL, "File \"%s\" does not exists, writing later", sFilename);
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
AQHMQTT_DEVICE_LIST *deviceList;
|
||||
|
||||
deviceList=_readDeviceFiles(aqh, sl);
|
||||
GWEN_StringList_free(sl);
|
||||
if (deviceList==NULL) {
|
||||
DBG_INFO(NULL, "Error reading sysconf device files");
|
||||
deviceList=AQHMQTT_Device_List_new();
|
||||
rv=_readDeviceFileToList(aqh, sFilename, deviceList);
|
||||
if (rv<0) {
|
||||
DBG_ERROR(NULL, "File \"%s\" not found", sFilename);
|
||||
AQHMQTT_Device_List_free(deviceList);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (AQHMQTT_Device_List_GetCount(deviceList)<1) {
|
||||
AQHMQTT_Device_List_free(deviceList);
|
||||
return NULL;
|
||||
}
|
||||
return deviceList;
|
||||
}
|
||||
else {
|
||||
DBG_INFO(NULL, "No sysconf device files");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -119,12 +126,12 @@ AQHMQTT_DEVICE_LIST *_readDeviceFiles(AQHOME_MQTT *aqh, const GWEN_STRINGLIST *s
|
||||
|
||||
s=GWEN_StringListEntry_Data(se);
|
||||
if (s && *s) {
|
||||
AQHMQTT_DEVICE *device;
|
||||
int rv;
|
||||
|
||||
device=_readDeviceFile(aqh, s);
|
||||
if (device) {
|
||||
DBG_ERROR(NULL, "Adding device \"%s\" to list", AQHMQTT_Device_GetName(device));
|
||||
AQHMQTT_Device_List_Add(device, deviceList);
|
||||
DBG_INFO(NULL, "Reading device file \"%s\"", s);
|
||||
rv=_readDeviceFileToList(aqh, s, deviceList);
|
||||
if (rv<0 && rv!=GWEN_ERROR_NO_DATA) {
|
||||
DBG_WARN(NULL, "Error reading device file \"%s\" (%d), ignoring", s, rv);
|
||||
}
|
||||
}
|
||||
se=GWEN_StringListEntry_Next(se);
|
||||
@@ -140,11 +147,10 @@ AQHMQTT_DEVICE_LIST *_readDeviceFiles(AQHOME_MQTT *aqh, const GWEN_STRINGLIST *s
|
||||
|
||||
|
||||
|
||||
|
||||
AQHMQTT_DEVICE *_readDeviceFile(AQHOME_MQTT *aqh, const char *sFilename)
|
||||
int _readDeviceFileToList(AQHOME_MQTT *aqh, const char *sFilename, AQHMQTT_DEVICE_LIST *deviceList)
|
||||
{
|
||||
GWEN_XMLNODE *rootNode;
|
||||
GWEN_XMLNODE *deviceNode;
|
||||
GWEN_XMLNODE *deviceListNode;
|
||||
int rv;
|
||||
|
||||
rootNode=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, NULL);
|
||||
@@ -152,36 +158,72 @@ AQHMQTT_DEVICE *_readDeviceFile(AQHOME_MQTT *aqh, const char *sFilename)
|
||||
if (rv<0) {
|
||||
DBG_ERROR(NULL, "Error reading XML file \"%s\": %d", sFilename, rv);
|
||||
GWEN_XMLNode_free(rootNode);
|
||||
return NULL;
|
||||
return rv;
|
||||
}
|
||||
deviceNode=GWEN_XMLNode_FindFirstTag(rootNode, "device", NULL, NULL);
|
||||
if (deviceNode) {
|
||||
const char *driverName;
|
||||
|
||||
driverName=GWEN_XMLNode_GetProperty(deviceNode, "driver", NULL);
|
||||
if (driverName && *driverName && strcasecmp(driverName, "mqtt")==0) {
|
||||
AQHMQTT_DEVICE *device;
|
||||
deviceListNode=GWEN_XMLNode_FindFirstTag(rootNode, "devices", NULL, NULL);
|
||||
if (deviceListNode==NULL)
|
||||
deviceListNode=rootNode;
|
||||
|
||||
device=_readXmlDevice(aqh, deviceNode);
|
||||
GWEN_XMLNode_free(rootNode);
|
||||
if (device==NULL) {
|
||||
DBG_INFO(NULL, "Error reading device from XML file \"%s\" (%d)", sFilename, rv);
|
||||
return NULL;
|
||||
}
|
||||
return device;
|
||||
}
|
||||
else {
|
||||
DBG_INFO(NULL, "Device is not an MQTT device, ignoring");
|
||||
}
|
||||
}
|
||||
else {
|
||||
DBG_INFO(NULL, "XML file \"%s\" does not contain a <device> element", sFilename);
|
||||
rv=_readXmlDevices(aqh, deviceListNode, deviceList);
|
||||
if (rv<0 && rv!=GWEN_ERROR_NO_DATA) {
|
||||
DBG_ERROR(AQH_LOGDOMAIN, "Error reading devices from file \"%s\" (%d)", sFilename, rv);
|
||||
GWEN_XMLNode_free(rootNode);
|
||||
return NULL;
|
||||
return rv;
|
||||
}
|
||||
|
||||
GWEN_XMLNode_free(rootNode);
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int _readXmlDevices(AQHOME_MQTT *aqh, GWEN_XMLNODE *deviceListNode, AQHMQTT_DEVICE_LIST *deviceList)
|
||||
{
|
||||
GWEN_XMLNODE *deviceNode;
|
||||
int rv;
|
||||
|
||||
deviceNode=GWEN_XMLNode_FindFirstTag(deviceListNode, "device", NULL, NULL);
|
||||
if (deviceNode) {
|
||||
while(deviceNode) {
|
||||
const char *driverName;
|
||||
|
||||
driverName=GWEN_XMLNode_GetProperty(deviceNode, "driver", NULL);
|
||||
if (driverName && *driverName && strcasecmp(driverName, "mqtt")==0) {
|
||||
AQHMQTT_DEVICE *device;
|
||||
|
||||
device=_readXmlDevice(aqh, deviceNode);
|
||||
if (device==NULL) {
|
||||
DBG_INFO(NULL, "Error reading device from XML (%d)", rv);
|
||||
return GWEN_ERROR_BAD_DATA;
|
||||
}
|
||||
else {
|
||||
const char *sDeviceId;
|
||||
const char *sDeviceName;
|
||||
|
||||
sDeviceId=AQHMQTT_Device_GetId(device);
|
||||
sDeviceName=AQHMQTT_Device_GetName(device);
|
||||
if (sDeviceId && *sDeviceId) {
|
||||
DBG_ERROR(NULL, "Adding device \"%s\" (%s) to list", sDeviceId, sDeviceName?sDeviceName:"<no type name>");
|
||||
}
|
||||
else {
|
||||
DBG_ERROR(NULL, "Adding device type \"%s\" to list", sDeviceName?sDeviceName:"<no type name>");
|
||||
}
|
||||
AQHMQTT_Device_List_Add(device, deviceList);
|
||||
}
|
||||
}
|
||||
else {
|
||||
DBG_INFO(NULL, "Device is not an MQTT device, ignoring");
|
||||
}
|
||||
deviceNode=GWEN_XMLNode_FindNextTag(deviceNode, "device", NULL, NULL);
|
||||
} /* while */
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
DBG_INFO(NULL, "No <device> element found");
|
||||
return GWEN_ERROR_NO_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -274,6 +316,7 @@ AQHMQTT_TOPIC *_readXmlTopic(AQHOME_MQTT *aqh, GWEN_XMLNODE *topicNode)
|
||||
}
|
||||
AQHMQTT_Topic_SetDirection(topic, i);
|
||||
|
||||
AQHMQTT_Topic_SetName(topic, GWEN_XMLNode_GetProperty(topicNode, "name", NULL));
|
||||
AQHMQTT_Topic_SetTopic(topic, GWEN_XMLNode_GetCharValue(topicNode, "topic", NULL));
|
||||
AQHMQTT_Topic_SetMask(topic, GWEN_XMLNode_GetCharValue(topicNode, "mask", NULL));
|
||||
AQHMQTT_Topic_SetBeforeId(topic, GWEN_XMLNode_GetCharValue(topicNode, "beforeId", NULL));
|
||||
|
||||
Reference in New Issue
Block a user