diff --git a/apps/aqhome-tool/data/0BUILD b/apps/aqhome-tool/data/0BUILD
index 359c2f9..ed2824c 100644
--- a/apps/aqhome-tool/data/0BUILD
+++ b/apps/aqhome-tool/data/0BUILD
@@ -43,6 +43,7 @@
setdata.h
moddevice.h
watch.h
+ devicestate.h
@@ -58,6 +59,7 @@
setdata.c
moddevice.c
watch.c
+ devicestate.c
diff --git a/apps/aqhome-tool/data/devicestate.c b/apps/aqhome-tool/data/devicestate.c
new file mode 100644
index 0000000..c6f9dcb
--- /dev/null
+++ b/apps/aqhome-tool/data/devicestate.c
@@ -0,0 +1,260 @@
+/****************************************************************************
+ * This file is part of the project AqHome.
+ * AqHome (c) by 2025 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 "./devicestate.h"
+#include "../utils.h"
+
+#include "aqhome/aqhome.h"
+#include "aqhome/dataclient/client.h"
+#include "aqhome/msg/ipc/m_ipc.h"
+#include "aqhome/msg/ipc/m_ipc_result.h"
+#include "aqhome/msg/ipc/data/m_ipcd.h"
+#include "aqhome/msg/ipc/data/m_ipcd_getdata.h"
+#include "aqhome/msg/ipc/data/m_ipcd_multidata.h"
+#include "aqhome/dataclient/client.h"
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+
+
+/* ------------------------------------------------------------------------------------------------
+ * defs
+ * ------------------------------------------------------------------------------------------------
+ */
+
+#define I18S(msg) msg
+#define I18N(msg) GWEN_I18N_Translate(PACKAGE, msg)
+
+#define A_ARG GWEN_ARGS_FLAGS_HAS_ARGUMENT
+#define A_END (GWEN_ARGS_FLAGS_HELP | GWEN_ARGS_FLAGS_LAST)
+#define A_CHAR GWEN_ArgsType_Char
+#define A_INT GWEN_ArgsType_Int
+
+
+
+/* ------------------------------------------------------------------------------------------------
+ * forward declarations
+ * ------------------------------------------------------------------------------------------------
+ */
+
+static int _runCommand(AQH_DATACLIENT *dc);
+static void _handleDevice(AQH_DATACLIENT *dc, const AQH_DEVICE *device);
+static void _handleValue(AQH_DATACLIENT *dc, const AQH_DEVICE *device, const AQH_VALUE *value);
+static void _printDataPoints(const uint64_t *dataPoints, uint32_t numValues);
+static void _printSingleDataPoint(uint64_t timestamp, double data);
+
+
+
+
+/* ------------------------------------------------------------------------------------------------
+ * code
+ * ------------------------------------------------------------------------------------------------
+ */
+
+int AQH_Tool_DeviceState(GWEN_DB_NODE *dbGlobalArgs, int argc, char **argv)
+{
+ AQH_EVENT_LOOP *eventLoop;
+ AQH_DATACLIENT *dc;
+ int rv;
+ const GWEN_ARGS args[]= {
+ /* flags type name min max s long short_descr, long_descr */
+ { A_ARG, A_CHAR, "brokerAddress", 0, 1, "t", "tcpaddress", I18S("TCP address to connect to [127.0.0.1]"), NULL},
+ { A_ARG, A_INT, "brokerPort", 0, 1, "P", "tcpport", I18S("Specify the TCP port to listen on"), NULL},
+ { A_ARG, A_INT, "timeout", 0, 1, "T", NULL, I18S("Specify timeout in seconds for response"), NULL},
+ { A_ARG, A_CHAR, "brokerClientId", 0, 1, "c", "clientid", I18S("Specify CLIENTID"), NULL},
+ { A_ARG, A_CHAR, "userId", 0, 1, "u", "userid", I18S("Specify user id"), NULL},
+ { A_ARG, A_CHAR, "password", 0, 1, "p", "password", I18S("Specify service password"), NULL},
+ { A_ARG, A_CHAR, "device", 1, 1, "d", "device", I18S("device name"), NULL},
+ { A_ARG, A_INT, "numOfDatapoints", 0, 1, "n", NULL, I18S("Get up to n datapoints"), NULL},
+ { A_END, A_INT, "help", 0, 0, "h", "help", I18S("Show this help screen"), NULL}
+ };
+
+ eventLoop=AQH_EventLoop_new();
+ dc=AQH_DataClient_new(eventLoop, AQH_IPC_PROTOCOL_DATA_ID, AQH_IPC_PROTOCOL_DATA_VERSION);
+
+ rv=AQH_DataClient_ReadLocalArgs(dc, dbGlobalArgs, args, argc, argv);
+ if (rv<0) {
+ DBG_ERROR(NULL, "here (%d)", rv);
+ AQH_DataClient_free(dc);
+ AQH_EventLoop_free(eventLoop);
+ return 2;
+ }
+
+ rv=AQH_DataClient_ConnectWithArgs(dc, 0);
+ if (rv<0) {
+ DBG_ERROR(NULL, "Error connecting (%d)", rv);
+ AQH_DataClient_free(dc);
+ AQH_EventLoop_free(eventLoop);
+ return 2;
+ }
+
+ rv=_runCommand(dc);
+ if (rv<0) {
+ DBG_ERROR(NULL, "Error running (%d)", rv);
+ AQH_DataClient_free(dc);
+ AQH_EventLoop_free(eventLoop);
+ return 2;
+ }
+
+ AQH_DataClient_free(dc);
+ AQH_EventLoop_free(eventLoop);
+ return 0;
+}
+
+
+
+int _runCommand(AQH_DATACLIENT *dc)
+{
+ GWEN_DB_NODE *dbLocalArgs;
+ const char *deviceName;
+ AQH_DEVICE_LIST *deviceList;
+ AQH_DEVICE *device;
+
+ dbLocalArgs=AQH_DataClient_GetDbLocalArgs(dc);
+ deviceName=GWEN_DB_GetCharValue(dbLocalArgs, "device", 0, "*");
+
+ deviceList=AQH_DataClient_GetDevices(dc);
+ if (deviceList==NULL) {
+ DBG_ERROR(NULL, "Error getting devices");
+ return GWEN_ERROR_GENERIC;
+ }
+
+ device=AQH_Device_List_First(deviceList);
+ while(device) {
+ const char *s;
+
+ s=AQH_Device_GetNameForSystem(device);
+ if (s && *s && -1!=GWEN_Text_ComparePattern(s, deviceName, 0)) {
+ _handleDevice(dc, device);
+ }
+
+ device=AQH_Device_List_Next(device);
+ }
+
+ AQH_Device_List_free(deviceList);
+
+ return 0;
+}
+
+
+
+void _handleDevice(AQH_DATACLIENT *dc, const AQH_DEVICE *device)
+{
+ AQH_VALUE_LIST *valueList;
+ const char *devName;
+ const char *roomName;
+ const char *location;
+ const char *descr;
+
+ devName=AQH_Device_GetNameForSystem(device);
+ roomName=AQH_Device_GetRoomName(device);
+ location=AQH_Device_GetLocation(device);
+ descr=AQH_Device_GetDescription(device);
+
+ fprintf(stdout, "%s (room: %s, loc: %s, descr: %s)\n",
+ devName,
+ roomName?roomName:"--",
+ location?location:"--",
+ descr?descr:"--");
+ valueList=AQH_DataClient_GetValues(dc, devName, 0);
+ if (valueList) {
+ const AQH_VALUE *value;
+
+ value=AQH_Value_List_First(valueList);
+ while(value) {
+ if (AQH_Value_GetValueType(value)==AQH_ValueType_Sensor)
+ _handleValue(dc, device, value);
+ value=AQH_Value_List_Next(value);
+ }
+ }
+
+ AQH_Value_List_free(valueList);
+}
+
+
+
+void _handleValue(AQH_DATACLIENT *dc, const AQH_DEVICE *device, const AQH_VALUE *value)
+{
+ GWEN_DB_NODE *dbLocalArgs;
+ const char *valueName;
+ int numDataPoints;
+
+ dbLocalArgs=AQH_DataClient_GetDbLocalArgs(dc);
+ numDataPoints=GWEN_DB_GetIntValue(dbLocalArgs, "numOfDatapoints", 0, 5);
+
+ valueName=AQH_Value_GetName(value);
+ if (valueName && -1==GWEN_Text_ComparePattern(valueName, "stats_*", 0)) {
+ const char *valueNameForSystem;
+ uint64_t *dataPoints;
+ uint64_t recvdNum;
+
+ valueNameForSystem=AQH_Value_GetNameForSystem(value);
+ fprintf(stdout, " %s: ", valueName?valueName:"");
+
+ dataPoints=malloc(numDataPoints*sizeof(uint64_t)*2);
+
+ recvdNum=AQH_DataClient_GetLastData(dc, valueNameForSystem, dataPoints, numDataPoints);
+ if (recvdNum>0)
+ _printDataPoints(dataPoints, recvdNum);
+
+ free(dataPoints);
+ fprintf(stdout, "\n");
+ }
+}
+
+
+
+void _printDataPoints(const uint64_t *dataPoints, uint32_t numValues)
+{
+ uint32_t i;
+
+ for(i=0; i
+
+
+
+int AQH_Tool_DeviceState(GWEN_DB_NODE *dbGlobalArgs, int argc, char **argv);
+
+
+#endif
+
diff --git a/apps/aqhome-tool/main.c b/apps/aqhome-tool/main.c
index a13cb83..ba251fe 100644
--- a/apps/aqhome-tool/main.c
+++ b/apps/aqhome-tool/main.c
@@ -23,6 +23,7 @@
#include "./data/setdata.h"
#include "./data/moddevice.h"
#include "./data/watch.h"
+#include "./data/devicestate.h"
#include
#include
@@ -101,6 +102,7 @@ int main(int argc, char **argv)
GWEN_FE_DAH("setdata", AQH_Tool_SetData, I18N("Set data for a value on the data server (e.g. a switch or thermostat)")),
GWEN_FE_DAH("moddevice", AQH_Tool_ModDevice, I18N("Modify a device on the data server")),
GWEN_FE_DAH("watch", AQH_Tool_Watch, I18N("Watch and print changes of values on the data server")),
+ GWEN_FE_DAH("devicestate", AQH_Tool_DeviceState, I18N("Show state of devices")),
GWEN_FE_END(),
};
const GWEN_FUNCS *func;