From d0c8b3b284c8ec192d491d290f662beae4bcca1a Mon Sep 17 00:00:00 2001 From: Martin Preuss Date: Tue, 7 Oct 2025 23:50:50 +0200 Subject: [PATCH] let setData use double values instead of strings. this allows for storing value set with setData which can then be used in the cgi module to retrieve the last value set. --- apps/aqhome-cgi/modules/mdevices.c | 240 ++++++++++++++------- apps/aqhome-data/s_setdata.c | 35 ++- apps/aqhome-mqttlog/s_setdata.c | 74 +++++-- apps/aqhome-mqttlog/types/translation.t2d | 6 +- apps/aqhome-mqttlog/xmlread.c | 8 +- apps/aqhome-mqttlog/xmlwrite.c | 2 +- apps/aqhome-nodes/r_setdata.c | 5 +- apps/aqhome-react/examples/001-tvlight.xml | 12 +- apps/aqhome-react/networks/delayedoff.xml | 2 +- apps/aqhome-react/types/prgrule.c | 27 ++- apps/aqhome-react/units/u_valueset.c | 36 +--- apps/aqhome-tool/data/setdata.c | 54 ++++- aqhome/aqhome.c | 57 +++++ aqhome/aqhome.h | 1 + aqhome/dataclient/client.c | 2 +- aqhome/dataclient/client.h | 2 +- aqhome/msg/ipc/data/m_ipcd_setdata.c | 18 +- aqhome/msg/ipc/data/m_ipcd_setdata.h | 4 +- aqhome/msg/ipc/m_ipc_tag16.c | 13 ++ aqhome/msg/ipc/m_ipc_tag16.h | 1 + devices/mqtt/tasmota_plug.xml | 4 +- devices/mqtt/tasmota_plug_old.xml | 4 +- 22 files changed, 421 insertions(+), 186 deletions(-) diff --git a/apps/aqhome-cgi/modules/mdevices.c b/apps/aqhome-cgi/modules/mdevices.c index baca810..3b57ca0 100644 --- a/apps/aqhome-cgi/modules/mdevices.c +++ b/apps/aqhome-cgi/modules/mdevices.c @@ -55,10 +55,14 @@ static void _runIndex(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQ static void _runValues(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf); static void _runSetData(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf); -static void _writeValueListToTable(const AQH_VALUE_LIST *valueList, GWEN_BUFFER *dbuf); -static void _writeValueToTable(const AQH_VALUE *value, GWEN_BUFFER *dbuf); +static void _writeValueListToTable(AQH_DATACLIENT *dc, const AQH_VALUE_LIST *valueList, GWEN_BUFFER *dbuf); +static void _writeValueToTable(AQH_DATACLIENT *dc, const AQH_VALUE *value, GWEN_BUFFER *dbuf); static void _addValueActionToForm(const AQH_VALUE *value, GWEN_BUFFER *dbuf); static uint32_t _colorFromHexString(const char *s); +static void _setRgbwData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue); +static void _setOnOffData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue); +static void _setOnOffAutoData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue); +static void _addLastValueToForm(AQH_DATACLIENT *dc, const AQH_VALUE *value, GWEN_BUFFER *dbuf); @@ -309,7 +313,7 @@ void _runValues(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DATA GBAS(dbuf,"
\n"); GBAA(dbuf, "\n", sDeviceName); - _writeValueListToTable(valueList, dbuf); + _writeValueListToTable(dc, valueList, dbuf); GBAS(dbuf,""); GBAS(dbuf, "
\n\n"); @@ -341,86 +345,17 @@ void _runSetData(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DAT value=AQH_Value_List_First(valueList); while(value) { if (AQH_Value_GetValueType(value)==AQH_ValueType_Actor) { - const char *sValueSystemName; const char *sValueName; const char *sValue; - int rv; - sValueSystemName=AQH_Value_GetNameForSystem(value); sValueName=AQH_Value_GetName(value); sValue=GWEN_DB_GetCharValue(dbPost, sValueName, 0, NULL); if (sValueName && *sValueName) { DBG_ERROR(NULL, "Setting value %s to %s", sValueName?sValueName:"no name", sValue?sValue:"no value"); switch(AQH_Value_GetModality(value)) { - case AQH_ValueModality_RGBW: - if (sValue) { - uint32_t color; - char colbuf[16]; - - color=_colorFromHexString(sValue); - snprintf(colbuf, sizeof(colbuf), "0x%08x", color); - DBG_ERROR(NULL, "Send value [%s] to %s", colbuf, sValueSystemName); - rv=AQH_DataClient_SetData(dc, value, colbuf); - if (rv<0) { - DBG_ERROR(NULL, "Error sending data: %d", rv); - GBAA(dbuf, "

Error setting value for %s

", sValueSystemName); - } - } - break; - case AQH_ValueModality_OnOff: - if (sValue) { - if (strcasecmp(sValue, "unchanged")==0) { - DBG_ERROR(NULL, "Value %s unchanged", sValueSystemName); - } - else if (strcasecmp(sValue, "on")==0) { - DBG_ERROR(NULL, "Send value 1 to %s", sValueSystemName); - rv=AQH_DataClient_SetData(dc, value, "1"); - if (rv<0) { - DBG_ERROR(NULL, "Error sending data: %d", rv); - } - } - else if (strcasecmp(sValue, "off")==0) { - DBG_ERROR(NULL, "Send value 0 to %s", sValueSystemName); - rv=AQH_DataClient_SetData(dc, value, "0"); - if (rv<0) { - DBG_ERROR(NULL, "Error sending data: %d", rv); - } - } - else { - } - } - break; - case AQH_ValueModality_OnOffAuto: - if (sValue) { - if (strcasecmp(sValue, "unchanged")==0) { - DBG_ERROR(NULL, "Value %s unchanged", sValueSystemName); - } - else if (strcasecmp(sValue, "on")==0) { - DBG_ERROR(NULL, "Send value 1 to %s", sValueSystemName); - rv=AQH_DataClient_SetData(dc, value, "1"); - if (rv<0) { - DBG_ERROR(NULL, "Error sending data: %d", rv); - } - } - else if (strcasecmp(sValue, "off")==0) { - DBG_ERROR(NULL, "Send value 0 to %s", sValueSystemName); - rv=AQH_DataClient_SetData(dc, value, "0"); - if (rv<0) { - DBG_ERROR(NULL, "Error sending data: %d", rv); - } - } - else if (strcasecmp(sValue, "auto")==0) { - DBG_ERROR(NULL, "Send value 2 to %s", sValueSystemName); - rv=AQH_DataClient_SetData(dc, value, "2"); - if (rv<0) { - DBG_ERROR(NULL, "Error sending data: %d", rv); - } - } - else { - DBG_ERROR(NULL, "Invalid value [%s] for %s", sValue, sValueSystemName); - } - } - break; + case AQH_ValueModality_RGBW: _setRgbwData(dc, value, sValue); break; + case AQH_ValueModality_OnOff: _setOnOffData(dc, value, sValue); break; + case AQH_ValueModality_OnOffAuto: _setOnOffAutoData(dc, value, sValue); break; default: break; } /* switch */ @@ -428,10 +363,8 @@ void _runSetData(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DAT } value=AQH_Value_List_Next(value); } /* while */ - - } - AQH_Value_List_free(valueList); + AQH_Value_List_free(valueList); if (sDeviceName && *sDeviceName) { GWEN_BUFFER *pbuf; @@ -448,7 +381,7 @@ void _runSetData(AQH_MODULE *m, AQCGI_REQUEST *rq, AQH_SESSION *session, AQH_DAT -void _writeValueListToTable(const AQH_VALUE_LIST *valueList, GWEN_BUFFER *dbuf) +void _writeValueListToTable(AQH_DATACLIENT *dc, const AQH_VALUE_LIST *valueList, GWEN_BUFFER *dbuf) { const AQH_VALUE *value; @@ -471,7 +404,7 @@ void _writeValueListToTable(const AQH_VALUE_LIST *valueList, GWEN_BUFFER *dbuf) value=AQH_Value_List_First(valueList); while(value) { - _writeValueToTable(value, dbuf); + _writeValueToTable(dc, value, dbuf); value=AQH_Value_List_Next(value); } GBAS(dbuf, @@ -481,7 +414,7 @@ void _writeValueListToTable(const AQH_VALUE_LIST *valueList, GWEN_BUFFER *dbuf) -void _writeValueToTable(const AQH_VALUE *value, GWEN_BUFFER *dbuf) +void _writeValueToTable(AQH_DATACLIENT *dc, const AQH_VALUE *value, GWEN_BUFFER *dbuf) { const char *s; @@ -508,8 +441,7 @@ void _writeValueToTable(const AQH_VALUE *value, GWEN_BUFFER *dbuf) #endif GBAS(dbuf, ""); - if (AQH_Value_GetValueType(value)==AQH_ValueType_Actor) - _addValueActionToForm(value, dbuf); + _addLastValueToForm(dc, value, dbuf); GBAS(dbuf, ""); GBAA(dbuf, "\n"); @@ -579,6 +511,148 @@ uint32_t _colorFromHexString(const char *s) +void _setRgbwData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue) +{ + if (sValue) { + const char *sValueSystemName; + uint32_t color; + int rv; + + sValueSystemName=AQH_Value_GetNameForSystem(value); + color=_colorFromHexString(sValue); + DBG_ERROR(NULL, "Send value [#%08x] to %s", color, sValueSystemName); + rv=AQH_DataClient_SetData(dc, value, (double) color); + if (rv<0) { + DBG_ERROR(NULL, "Error sending data: %d", rv); + } + } +} + + + +void _setOnOffData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue) +{ + if (sValue) { + const char *sValueSystemName; + int rv; + + sValueSystemName=AQH_Value_GetNameForSystem(value); + if (strcasecmp(sValue, "unchanged")==0) { + DBG_ERROR(NULL, "Value %s unchanged", sValueSystemName); + } + else if (strcasecmp(sValue, "on")==0) { + DBG_ERROR(NULL, "Send value 1 to %s", sValueSystemName); + rv=AQH_DataClient_SetData(dc, value, 1.0); + if (rv<0) { + DBG_ERROR(NULL, "Error sending data: %d", rv); + } + } + else if (strcasecmp(sValue, "off")==0) { + DBG_ERROR(NULL, "Send value 0 to %s", sValueSystemName); + rv=AQH_DataClient_SetData(dc, value, 0.0); + if (rv<0) { + DBG_ERROR(NULL, "Error sending data: %d", rv); + } + } + else { + } + } +} + + + +void _setOnOffAutoData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue) +{ + if (sValue) { + const char *sValueSystemName; + int rv; + + sValueSystemName=AQH_Value_GetNameForSystem(value); + if (strcasecmp(sValue, "unchanged")==0) { + DBG_ERROR(NULL, "Value %s unchanged", sValueSystemName); + } + else if (strcasecmp(sValue, "on")==0) { + DBG_ERROR(NULL, "Send value 1 to %s", sValueSystemName); + rv=AQH_DataClient_SetData(dc, value, 1.0); + if (rv<0) { + DBG_ERROR(NULL, "Error sending data: %d", rv); + } + } + else if (strcasecmp(sValue, "off")==0) { + DBG_ERROR(NULL, "Send value 0 to %s", sValueSystemName); + rv=AQH_DataClient_SetData(dc, value, 0.0); + if (rv<0) { + DBG_ERROR(NULL, "Error sending data: %d", rv); + } + } + else if (strcasecmp(sValue, "auto")==0) { + DBG_ERROR(NULL, "Send value 2 to %s", sValueSystemName); + rv=AQH_DataClient_SetData(dc, value, 2.0); + if (rv<0) { + DBG_ERROR(NULL, "Error sending data: %d", rv); + } + } + else { + DBG_ERROR(NULL, "Invalid value [%s] for %s", sValue, sValueSystemName); + } + } +} + + + +void _addLastValueToForm(AQH_DATACLIENT *dc, const AQH_VALUE *value, GWEN_BUFFER *dbuf) +{ + const char *sValueSystemName; + const char *sValueName; + uint64_t dataPoints[2]; + uint64_t recvdNum; +// uint64_t timestamp; + union {double f; uint64_t i;} u; + int intVal; + + sValueSystemName=AQH_Value_GetNameForSystem(value); + sValueName=AQH_Value_GetName(value); + recvdNum=AQH_DataClient_GetLastData(dc, sValueSystemName, &dataPoints[0], 1); + if (recvdNum>0) { +// timestamp=dataPoints[0]; + u.i=dataPoints[1]; + intVal=(int) u.f; + } + else { + u.i=0; + intVal=-1; + } + + if (AQH_Value_GetValueType(value)==AQH_ValueType_Actor) { + DBG_ERROR(NULL, "Adding actor"); + switch(AQH_Value_GetModality(value)) { + case AQH_ValueModality_RGBW: + GBAA(dbuf, "", sValueName, (unsigned int) u.f); + break; + case AQH_ValueModality_OnOff: + GBAA(dbuf, ""); + break; + case AQH_ValueModality_OnOffAuto: + GBAA(dbuf, ""); + break; + default: +// GBAA(dbuf, "", sValueName, u.f); + GBAA(dbuf, "%.2f", u.f); + break; + } /* switch */ + } /* if actor */ + else { + DBG_ERROR(NULL, "Adding sensor (%s=%.2f)", sValueName, u.f); + GBAA(dbuf, "%.2f", u.f); + } +} diff --git a/apps/aqhome-data/s_setdata.c b/apps/aqhome-data/s_setdata.c index a80e113..aa4360b 100644 --- a/apps/aqhome-data/s_setdata.c +++ b/apps/aqhome-data/s_setdata.c @@ -42,14 +42,15 @@ * ------------------------------------------------------------------------------------------------ */ +static void _storeDatapoint(AQHOME_SERVER *xo, const AQH_VALUE *v, double valueData); static AQH_MSG_REQUEST *_mkRequest_SetData(AQH_OBJECT *o, AQH_OBJECT *epSrc, uint32_t requestMsgId, AQH_OBJECT *epDriver, - const AQH_VALUE *v, const char *data); + const AQH_VALUE *v, double data); static void _rqSubRequestFinished(AQH_MSG_REQUEST *rq, AQH_MSG_REQUEST *subRq, int reason); static void _rqAbort(AQH_MSG_REQUEST *rq, int reason); -static AQH_MSG_REQUEST *_mkSubRequest_SetData(AQH_OBJECT *o, AQH_OBJECT *epDriver, const AQH_VALUE *v, const char *data); +static AQH_MSG_REQUEST *_mkSubRequest_SetData(AQH_OBJECT *o, AQH_OBJECT *epDriver, const AQH_VALUE *v, double data); static int _subRqHandleResponse(AQH_MSG_REQUEST *rq, const AQH_MESSAGE *msg); static void _subRqAbort(AQH_MSG_REQUEST *rq, int reason); @@ -76,11 +77,11 @@ void AqHomeDataServer_HandleSetData(AQH_OBJECT *o, AQH_OBJECT *epSrc, const AQH_ recvdValue=AQH_IpcdMessageSetData_ReadValue(tagList); if (recvdValue) { const char *valueName; - char *valueDataFreeable; + double valueData; AQH_VALUE *systemValue; valueName=AQH_Value_GetNameForSystem(recvdValue); - valueDataFreeable=AQH_IpcdMessageSetData_ReadData(tagList); + valueData=AQH_IpcdMessageSetData_ReadData(tagList); systemValue=AQH_Storage_GetValueByNameForSystem(xo->storage, valueName); if (systemValue) { @@ -96,8 +97,10 @@ void AqHomeDataServer_HandleSetData(AQH_OBJECT *o, AQH_OBJECT *epSrc, const AQH_ AQH_MSG_REQUEST *rq; DBG_ERROR(NULL, "Creating SETDATA request for driver endpoint (%s)", AQH_Endpoint_GetServiceName(epDriver)); - rq=_mkRequest_SetData(o, epSrc, msgId, epDriver, systemValue, valueDataFreeable); + rq=_mkRequest_SetData(o, epSrc, msgId, epDriver, systemValue, valueData); AqHomeDataServer_AddRequestToTree(o, rq); + + _storeDatapoint(xo, systemValue, valueData); } else { DBG_ERROR(NULL, "Driver \"%s\" not available", driverName); @@ -119,7 +122,6 @@ void AqHomeDataServer_HandleSetData(AQH_OBJECT *o, AQH_OBJECT *epSrc, const AQH_ AqHomeDataServer_SendResponseResultToEndpoint(epSrc, msgId, AQH_MSGDATA_RESULT_ERROR_NOTFOUND); } AQH_Value_free(recvdValue); - free(valueDataFreeable); } /* if recvdValue */ else { DBG_ERROR(NULL, "No value in message"); @@ -131,6 +133,23 @@ void AqHomeDataServer_HandleSetData(AQH_OBJECT *o, AQH_OBJECT *epSrc, const AQH_ +void _storeDatapoint(AQHOME_SERVER *xo, const AQH_VALUE *v, double valueData) +{ + uint64_t timestamp; + int rv; + + timestamp=(uint64_t) time(NULL); + rv=AQH_Storage_AddDatapoint(xo->storage, AQH_Value_GetId(v), timestamp, valueData); + if (rv<0) { + DBG_INFO(NULL, "here (%d)", rv); + } + else { + DBG_INFO(NULL, "Datapoint added for value \"%s\"", AQH_Value_GetNameForSystem(v)); + } +} + + + /* ------------------------------------------------------------------------------------------------ * IPC Request SETDATA */ @@ -138,7 +157,7 @@ void AqHomeDataServer_HandleSetData(AQH_OBJECT *o, AQH_OBJECT *epSrc, const AQH_ AQH_MSG_REQUEST *_mkRequest_SetData(AQH_OBJECT *o, AQH_OBJECT *epSrc, uint32_t requestMsgId, AQH_OBJECT *epDriver, - const AQH_VALUE *v, const char *data) + const AQH_VALUE *v, double data) { AQH_MSG_REQUEST *rq; AQH_MSG_REQUEST *subRq; @@ -205,7 +224,7 @@ void _rqAbort(AQH_MSG_REQUEST *rq, int reason) */ -AQH_MSG_REQUEST *_mkSubRequest_SetData(AQH_OBJECT *o, AQH_OBJECT *epDriver, const AQH_VALUE *v, const char *data) +AQH_MSG_REQUEST *_mkSubRequest_SetData(AQH_OBJECT *o, AQH_OBJECT *epDriver, const AQH_VALUE *v, double data) { AQH_MSG_REQUEST *rq; uint16_t msgId; diff --git a/apps/aqhome-mqttlog/s_setdata.c b/apps/aqhome-mqttlog/s_setdata.c index 13aa5ea..74f1b05 100644 --- a/apps/aqhome-mqttlog/s_setdata.c +++ b/apps/aqhome-mqttlog/s_setdata.c @@ -30,8 +30,13 @@ */ static void _sendDataForDevice(AQH_MQTTLOG_SERVER *xo, const AQHMQTT_DEVICE *device, - const char *valueName, const char *valueData); -static void _sendValueToMqtt(AQH_MQTTLOG_SERVER *xo, const char *deviceId, const AQHMQTT_TOPIC *topic, const char *valueData); + const char *valueName, double valueData); +static void _sendValueToMqtt(AQH_MQTTLOG_SERVER *xo, + const AQHMQTT_DEVICE *device, + const AQHMQTT_TOPIC *topic, + const AQHMQTT_VALUE *value, + double valueData); +static const char *_valueTranslatedForDriver(const AQHMQTT_VALUE *value, double valueData); static GWEN_BUFFER *_createBufferForTopic(const char *deviceId, const AQHMQTT_TOPIC *topic); @@ -65,12 +70,11 @@ void AQH_MqttLogServer_HandleSetData(AQH_OBJECT *o, device=AQH_MqttLogServer_FindRegisteredDevice(o, deviceName); if (device) { - char *valueDataFreeable; + double valueData; DBG_ERROR(NULL, "Sending data to value \"%s\" of device \"%s\"", valueName, deviceName); - valueDataFreeable=AQH_IpcdMessageSetData_ReadData(tagList); - _sendDataForDevice(xo, device, valueName, valueDataFreeable); - free(valueDataFreeable); + valueData=AQH_IpcdMessageSetData_ReadData(tagList); + _sendDataForDevice(xo, device, valueName, valueData); } else { DBG_ERROR(NULL, "Device \"%s\" not found", deviceName); @@ -93,7 +97,7 @@ void AQH_MqttLogServer_HandleSetData(AQH_OBJECT *o, void _sendDataForDevice(AQH_MQTTLOG_SERVER *xo, const AQHMQTT_DEVICE *device, - const char *valueName, const char *valueData) + const char *valueName, double valueData) { const char *deviceId; @@ -116,7 +120,7 @@ void _sendDataForDevice(AQH_MQTTLOG_SERVER *xo, if (value) { /* found value, create publish msg, send */ DBG_ERROR(NULL, "Topic \"%s\" contains value \"%s\"", AQHMQTT_Topic_GetName(topic), valueName); - _sendValueToMqtt(xo, deviceId, topic, valueData); + _sendValueToMqtt(xo, device, topic, value, valueData); } } /* if out */ topic=AQHMQTT_Topic_List_Next(topic); @@ -130,32 +134,72 @@ void _sendDataForDevice(AQH_MQTTLOG_SERVER *xo, -void _sendValueToMqtt(AQH_MQTTLOG_SERVER *xo, const char *deviceId, const AQHMQTT_TOPIC *topic, const char *valueData) +void _sendValueToMqtt(AQH_MQTTLOG_SERVER *xo, + const AQHMQTT_DEVICE *device, + const AQHMQTT_TOPIC *topic, + const AQHMQTT_VALUE *value, + double valueData) { + const char *deviceId; + const char *translatedValue; GWEN_BUFFER *buf; #if !DEBUG_DRY_RUN AQH_MESSAGE *msgOut; #endif + deviceId=AQHMQTT_Device_GetId(device); buf=_createBufferForTopic(deviceId, topic); + translatedValue=_valueTranslatedForDriver(value, valueData); + if (translatedValue && *translatedValue) { + DBG_ERROR(NULL, "MQTT PUBLISH: %s = %s", GWEN_Buffer_GetStart(buf), translatedValue); + msgOut=AQH_MqttMessagePublish_new(0, 0, GWEN_Buffer_GetStart(buf), (const uint8_t*)translatedValue, strlen(translatedValue)); + } + else { + GWEN_BUFFER *vbuf; + + vbuf=GWEN_Buffer_new(0, 64, 0, 1); + GWEN_Buffer_AppendArgs(vbuf, "%f", valueData); + DBG_ERROR(NULL, "MQTT PUBLISH: %s = %s", GWEN_Buffer_GetStart(buf), GWEN_Buffer_GetStart(vbuf)); + msgOut=AQH_MqttMessagePublish_new(0, 0, + GWEN_Buffer_GetStart(buf), + (const uint8_t*)GWEN_Buffer_GetStart(vbuf), + GWEN_Buffer_GetUsedBytes(vbuf)); + GWEN_Buffer_free(vbuf); + } + #if !DEBUG_DRY_RUN - DBG_ERROR(NULL, "MQTT PUBLISH: %s = %s", GWEN_Buffer_GetStart(buf), valueData?valueData:""); - msgOut=AQH_MqttMessagePublish_new(0, 0, GWEN_Buffer_GetStart(buf), - (const uint8_t*) (valueData?valueData:NULL), - valueData?strlen(valueData):0); if (msgOut) AQH_Endpoint_AddMsgOut(xo->mqttEndpoint, msgOut); else { DBG_ERROR(NULL, "Error creating message"); } -#else - DBG_ERROR(NULL, "Would MQTT PUBLISH: %s = %s", GWEN_Buffer_GetStart(buf), valueData?valueData:""); #endif GWEN_Buffer_free(buf); } +const char *_valueTranslatedForDriver(const AQHMQTT_VALUE *value, double valueData) +{ + const AQHMQTT_TRANSLATION_LIST *translationList; + + translationList=AQHMQTT_Value_GetTranslationList(value); + if (translationList) { + const AQHMQTT_TRANSLATION *t; + int valueAsInt; + + valueAsInt=(int) valueData; + t=AQHMQTT_Translation_List_GetByAqhValue(translationList, valueAsInt); + if (t) { + return AQHMQTT_Translation_GetDriverValue(t); + } + } + + return NULL; +} + + + GWEN_BUFFER *_createBufferForTopic(const char *deviceId, const AQHMQTT_TOPIC *topic) { GWEN_BUFFER *buf; diff --git a/apps/aqhome-mqttlog/types/translation.t2d b/apps/aqhome-mqttlog/types/translation.t2d index ce1d4dc..edf5e6c 100644 --- a/apps/aqhome-mqttlog/types/translation.t2d +++ b/apps/aqhome-mqttlog/types/translation.t2d @@ -32,18 +32,18 @@ - + 0 0 public - own + with_getByMember 0 0 public - own + own with_getByMember diff --git a/apps/aqhome-mqttlog/xmlread.c b/apps/aqhome-mqttlog/xmlread.c index 06649b1..ddb19bd 100644 --- a/apps/aqhome-mqttlog/xmlread.c +++ b/apps/aqhome-mqttlog/xmlread.c @@ -458,16 +458,16 @@ AQHMQTT_TRANSLATION_LIST *_readXmlTranslationList(GWEN_XMLNODE *parentNode) AQHMQTT_TRANSLATION *_readXmlTranslation(GWEN_XMLNODE *translationNode) { - const char *sAqhValue; + int aqhValue; const char *sDriverValue; - sAqhValue=GWEN_XMLNode_GetProperty(translationNode, "aqhValue", NULL); + aqhValue=GWEN_XMLNode_GetIntProperty(translationNode, "aqhValue", 0); sDriverValue=GWEN_XMLNode_GetProperty(translationNode, "driverValue", NULL); - if (sAqhValue && *sAqhValue && sDriverValue && *sDriverValue) { + if (sDriverValue && *sDriverValue) { AQHMQTT_TRANSLATION *translation; translation=AQHMQTT_Translation_new(); - AQHMQTT_Translation_SetAqhValue(translation, sAqhValue); + AQHMQTT_Translation_SetAqhValue(translation, aqhValue); AQHMQTT_Translation_SetDriverValue(translation, sDriverValue); return translation; } diff --git a/apps/aqhome-mqttlog/xmlwrite.c b/apps/aqhome-mqttlog/xmlwrite.c index d6ea5ea..af56843 100644 --- a/apps/aqhome-mqttlog/xmlwrite.c +++ b/apps/aqhome-mqttlog/xmlwrite.c @@ -222,7 +222,7 @@ void _writeValueToXml(const AQHMQTT_VALUE *value, GWEN_XMLNODE *node) void _writeTranslationToXml(const AQHMQTT_TRANSLATION *t, GWEN_XMLNODE *nTranslation) { - _setXmlPropertyIfNotNull(nTranslation, "aqhValue", AQHMQTT_Translation_GetAqhValue(t)); + GWEN_XMLNode_SetIntProperty(nTranslation, "aqhValue", AQHMQTT_Translation_GetAqhValue(t)); _setXmlPropertyIfNotNull(nTranslation, "driverValue", AQHMQTT_Translation_GetDriverValue(t)); } diff --git a/apps/aqhome-nodes/r_setdata.c b/apps/aqhome-nodes/r_setdata.c index 9ad5a22..6a38c66 100644 --- a/apps/aqhome-nodes/r_setdata.c +++ b/apps/aqhome-nodes/r_setdata.c @@ -92,7 +92,7 @@ void AQH_NodeServer_HandleSetData(AQH_OBJECT *o, AQH_OBJECT *ep, const AQH_MESSA varName=AQH_Value_GetName(value); if (varName) { - char *data; + double data; data=AQH_IpcdMessageSetData_ReadData(tagList); if (data) { @@ -115,7 +115,7 @@ void AQH_NodeServer_HandleSetData(AQH_OBJECT *o, AQH_OBJECT *ep, const AQH_MESSA uint16_t dataVal=0; uint16_t dataDenom=0; - if (AQH_ReadDataFromString(AQHNODE_Value_GetDataType(devValue), data, &dataVal, &dataDenom)==0) { + if (AQH_ReadDataFromDouble(AQHNODE_Value_GetDataType(devValue), data, &dataVal, &dataDenom)==0) { AQH_MSG_REQUEST *rq; int destAddr; @@ -150,7 +150,6 @@ void AQH_NodeServer_HandleSetData(AQH_OBJECT *o, AQH_OBJECT *ep, const AQH_MESSA DBG_ERROR(NULL, "No matching nodeinfo"); _sendResponseResultToBroker(ep, msgId, AQH_MSGDATA_RESULT_ERROR_INVALID); } - free(data); } else { DBG_ERROR(NULL, "No data"); diff --git a/apps/aqhome-react/examples/001-tvlight.xml b/apps/aqhome-react/examples/001-tvlight.xml index 707e5a3..b8e7ec6 100644 --- a/apps/aqhome-react/examples/001-tvlight.xml +++ b/apps/aqhome-react/examples/001-tvlight.xml @@ -26,15 +26,6 @@ - - - OFF - OFF - ON - - - - mqtt/109C2F/power @@ -49,7 +40,6 @@ - - + diff --git a/apps/aqhome-react/networks/delayedoff.xml b/apps/aqhome-react/networks/delayedoff.xml index ec1fe52..587b201 100644 --- a/apps/aqhome-react/networks/delayedoff.xml +++ b/apps/aqhome-react/networks/delayedoff.xml @@ -12,7 +12,7 @@ - + diff --git a/apps/aqhome-react/types/prgrule.c b/apps/aqhome-react/types/prgrule.c index 8dcca13..a572687 100644 --- a/apps/aqhome-react/types/prgrule.c +++ b/apps/aqhome-react/types/prgrule.c @@ -312,10 +312,29 @@ const char *_readValueAndProbablyRange(const char *s, uint64_t *ptrBitField, int { int v=0; - while(isdigit(*s)) { - v*=10; - v+=(*s)-'0'; - s++; + if (*s=='#') { + while(*s) { + unsigned char c; + + c=tolower(*s); + if ((c>='0' && c<='9') || (c>='a' && c<='f')) { + c-='0'; + if (c>9) + c-=7; + v<<=4; + v+=c; + } + else + break; + s++; + } + } + else { + while(isdigit(*s)) { + v*=10; + v+=(*s)-'0'; + s++; + } } if (!_valueOkay(v, minValue, maxValue)) { DBG_INFO(NULL, "here"); diff --git a/apps/aqhome-react/units/u_valueset.c b/apps/aqhome-react/units/u_valueset.c index 2ac6fd4..4643174 100644 --- a/apps/aqhome-react/units/u_valueset.c +++ b/apps/aqhome-react/units/u_valueset.c @@ -38,7 +38,6 @@ */ static void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAOBJECT *dataObject); -static AQH_MESSAGE *_mkSetDataMsgString(AQH_OBJECT *brokerEndpoint, const char *sValueName, const AQHREACT_DATAOBJECT *dataObject); static AQH_MESSAGE *_mkSetDataMsgDouble(AQH_OBJECT *brokerEndpoint, const char *sValueName, const AQHREACT_DATAOBJECT *dataObject); @@ -62,12 +61,12 @@ AQHREACT_UNIT *AqHomeReact_UnitValueSet_new(AQH_OBJECT *aqh) port=AQHREACT_Port_new(); AQHREACT_Port_SetName(port, "input"); AQHREACT_Port_SetIdForUnit(port, AQHOMEREACT_UNIT_VALUESET_INSLOT_VALUE); - AQHREACT_Port_SetDataType(port, AQHREACT_DATAOBJECTTYPE_STRING); + AQHREACT_Port_SetDataType(port, AQHREACT_DATAOBJECTTYPE_DOUBLE); AQHREACT_Unit_AddInputPort(unit, port); param=AQHREACT_Param_new(); AQHREACT_Param_SetName(param, AQHOMEREACT_UNIT_VALUESET_PARAM_VALUENAME); - AQHREACT_Param_SetDataType(param, AQHREACT_DATAOBJECTTYPE_STRING); + AQHREACT_Param_SetDataType(param, AQHREACT_DATAOBJECTTYPE_DOUBLE); AQHREACT_Unit_AddParam(unit, param); return unit; @@ -92,9 +91,6 @@ void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAO case AQHREACT_DATAOBJECTTYPE_DOUBLE: msgOut=_mkSetDataMsgDouble(brokerEndpoint, sValueName, dataObject); break; - case AQHREACT_DATAOBJECTTYPE_STRING: - msgOut=_mkSetDataMsgString(brokerEndpoint, sValueName, dataObject); - break; default: DBG_ERROR(NULL, "Unhandled data type (%d)", AQHREACT_DataObject_GetDataType(dataObject)); msgOut=NULL; @@ -130,47 +126,21 @@ void _cbInputData(AQHREACT_UNIT *unit, AQHREACT_PORT *port, const AQHREACT_DATAO -AQH_MESSAGE *_mkSetDataMsgString(AQH_OBJECT *brokerEndpoint, const char *sValueName, const AQHREACT_DATAOBJECT *dataObject) -{ - AQH_MESSAGE *msgOut; - AQH_VALUE *v; - - v=AQH_Value_new(); - AQH_Value_SetNameForSystem(v, sValueName); - - msgOut=AQH_IpcdMessageSetData_new(AQH_MSGTYPE_IPC_DATA_SETDATA, - AQH_Endpoint_GetNextMessageId(brokerEndpoint), 0, - v, AQHREACT_DataObject_GetStringData(dataObject)); - AQH_Value_free(v); - return msgOut; -} - - - AQH_MESSAGE *_mkSetDataMsgDouble(AQH_OBJECT *brokerEndpoint, const char *sValueName, const AQHREACT_DATAOBJECT *dataObject) { AQH_MESSAGE *msgOut; AQH_VALUE *v; double data; - GWEN_BUFFER *buf; int rv; v=AQH_Value_new(); AQH_Value_SetNameForSystem(v, sValueName); data=AQHREACT_DataObject_GetDoubleData(dataObject); - buf=GWEN_Buffer_new(0, 64, 0, 1); - rv=GWEN_Text_DoubleToBuffer(data, buf); - if (rv<0) { - GWEN_Buffer_free(buf); - AQH_Value_free(v); - return NULL; - } msgOut=AQH_IpcdMessageSetData_new(AQH_MSGTYPE_IPC_DATA_SETDATA, AQH_Endpoint_GetNextMessageId(brokerEndpoint), 0, - v, GWEN_Buffer_GetStart(buf)); - GWEN_Buffer_free(buf); + v, data); AQH_Value_free(v); return msgOut; } diff --git a/apps/aqhome-tool/data/setdata.c b/apps/aqhome-tool/data/setdata.c index 2faee5a..e2b2024 100644 --- a/apps/aqhome-tool/data/setdata.c +++ b/apps/aqhome-tool/data/setdata.c @@ -45,6 +45,7 @@ */ static AQH_MESSAGE *_createRequestMessage(AQH_OBJECT *o, uint32_t msgId); +static int _readValueFromString(const char *s, double *pDouble); @@ -93,18 +94,30 @@ AQH_MESSAGE *_createRequestMessage(GWEN_UNUSED AQH_OBJECT *o, uint32_t msgId) GWEN_DB_NODE *dbArgs; const char *valueName; const char *valueUnits; - const char *valueData; + const char *valueDataAsString; + double valueData; AQH_VALUE *v; + int rv; dbArgs=AQH_ToolClient_GetDbLocalArgs(o); valueName=GWEN_DB_GetCharValue(dbArgs, "valueName", 0, NULL); valueUnits=GWEN_DB_GetCharValue(dbArgs, "valueUnits", 0, NULL); - valueData=GWEN_DB_GetCharValue(dbArgs, "value", 0, NULL); + valueDataAsString=GWEN_DB_GetCharValue(dbArgs, "value", 0, NULL); + + if (valueDataAsString && *valueDataAsString) { + rv=_readValueFromString(valueDataAsString, &valueData); + if (rv<0) { + DBG_ERROR(NULL, "ERROR: Bad value"); + return NULL; + } + } + if (!(valueName && *valueName)) { DBG_ERROR(NULL, "ERROR: Missing value name"); return NULL; } + v=AQH_Value_new(); AQH_Value_SetNameForSystem(v, valueName); AQH_Value_SetValueUnits(v, valueUnits); @@ -116,3 +129,40 @@ AQH_MESSAGE *_createRequestMessage(GWEN_UNUSED AQH_OBJECT *o, uint32_t msgId) +int _readValueFromString(const char *s, double *pDouble) +{ + int l; + + l=strlen(s); + if (l) { + if (*s=='#') { + unsigned int h; + + if (1==sscanf(s+1, "%x", &h)) { + *pDouble=(double) h; + return 0; + } + } + else if (l>1 && s[0]=='0' && ((tolower(s[1])=='x') || tolower(s[1])=='b')) { + unsigned int h; + + if (1==sscanf(s, "%u", &h)) { + *pDouble=(double) h; + return 0; + } + } + else { + double d; + + if (1==sscanf(s, "%lf", &d)) { + return d; + } + } + DBG_ERROR(NULL, "Bad value \"%s\"", s); + return GWEN_ERROR_GENERIC; + } +} + + + + diff --git a/aqhome/aqhome.c b/aqhome/aqhome.c index bee2f17..39ff339 100644 --- a/aqhome/aqhome.c +++ b/aqhome/aqhome.c @@ -43,6 +43,10 @@ static void _definePath(const char *pathName, const char *pathValue); static GWEN_STRINGLIST *_getListOfMatchingFiles(const char *pathName, const char *subFolder, const char *mask); static GWEN_BUFFER *_getRuntimeFilePath(const char *pathName, const char *sFilename); static GWEN_BUFFER *_findFileinPath(const char *pathName, const char *sFilename); +static int _readUint8DataFromDouble(double d, uint16_t *pDataVal, uint16_t *pDataDenom); +static int _readUint16DataFromDouble(double d, uint16_t *pDataVal, uint16_t *pDataDenom); +static int _readUint32DataFromDouble(double d, uint16_t *pDataVal, uint16_t *pDataDenom); + static int _readUint8DataFromString(const char *s, uint16_t *pDataVal, uint16_t *pDataDenom); static int _readUint16DataFromString(const char *s, uint16_t *pDataVal, uint16_t *pDataDenom); static int _readUint32DataFromString(const char *s, uint16_t *pDataVal, uint16_t *pDataDenom); @@ -469,6 +473,59 @@ GWEN_BUFFER *_findFileinPath(const char *pathName, const char *sFilename) +int AQH_ReadDataFromDouble(int dataType, double d, uint16_t *pDataVal, uint16_t *pDataDenom) +{ + switch(dataType) { + case AQH_ValueDataType_Uint8: return _readUint8DataFromDouble(d, pDataVal, pDataDenom); + case AQH_ValueDataType_Int: + case AQH_ValueDataType_Uint16: return _readUint16DataFromDouble(d, pDataVal, pDataDenom); + case AQH_ValueDataType_Uint32: return _readUint32DataFromDouble(d, pDataVal, pDataDenom); + case AQH_ValueDataType_Rational: break; + default: break; + } + + return GWEN_ERROR_INVALID; +} + + + +int _readUint8DataFromDouble(double d, uint16_t *pDataVal, uint16_t *pDataDenom) +{ + uint8_t v; + + v=((uint8_t) (d)) & 0xff; + *pDataVal=v & 0xff; + *pDataDenom=1; + return 0; +} + + + +int _readUint16DataFromDouble(double d, uint16_t *pDataVal, uint16_t *pDataDenom) +{ + uint16_t v; + + v=((uint16_t) d) & 0xffff; + *pDataVal=v; + *pDataDenom=1; + return 0; +} + + + +int _readUint32DataFromDouble(double d, uint16_t *pDataVal, uint16_t *pDataDenom) +{ + uint32_t v; + + v=((uint32_t) d) & 0xffffffff; + + *pDataVal=(v>>16) & 0xffff; + *pDataDenom=v & 0xffff; + return 0; +} + + + int AQH_ReadDataFromString(int dataType, const char *s, uint16_t *pDataVal, uint16_t *pDataDenom) { if (s && *s) { diff --git a/aqhome/aqhome.h b/aqhome/aqhome.h index d86f540..ff159af 100644 --- a/aqhome/aqhome.h +++ b/aqhome/aqhome.h @@ -84,6 +84,7 @@ AQHOME_API int AQH_ValueModality_fromString(const char *s); AQHOME_API const char *AQH_ValueModality_toString(int i); AQHOME_API int AQH_ReadDataFromString(int dataType, const char *s, uint16_t *pDataVal, uint16_t *pDataDenom); +AQHOME_API int AQH_ReadDataFromDouble(int dataType, double d, uint16_t *pDataVal, uint16_t *pDataDenom); #endif diff --git a/aqhome/dataclient/client.c b/aqhome/dataclient/client.c index 9b6336e..7d94c39 100644 --- a/aqhome/dataclient/client.c +++ b/aqhome/dataclient/client.c @@ -343,7 +343,7 @@ uint64_t AQH_DataClient_GetPeriodData(AQH_DATACLIENT *dc, const char *valueName, -int AQH_DataClient_SetData(AQH_DATACLIENT *dc, const AQH_VALUE *v, const char *data) +int AQH_DataClient_SetData(AQH_DATACLIENT *dc, const AQH_VALUE *v, double data) { if (dc) { AQH_MESSAGE *msgOut; diff --git a/aqhome/dataclient/client.h b/aqhome/dataclient/client.h index 1a77195..f6071ac 100644 --- a/aqhome/dataclient/client.h +++ b/aqhome/dataclient/client.h @@ -43,7 +43,7 @@ AQHOME_API uint64_t AQH_DataClient_GetPeriodData(AQH_DATACLIENT *dc, const char uint64_t *dataPtr, uint64_t maxNum, uint64_t tsBegin, uint64_t tsEnd); -AQHOME_API int AQH_DataClient_SetData(AQH_DATACLIENT *dc, const AQH_VALUE *v, const char *data); +AQHOME_API int AQH_DataClient_SetData(AQH_DATACLIENT *dc, const AQH_VALUE *v, double data); AQHOME_API int AQH_DataClient_UpdateData(AQH_DATACLIENT *dc, const AQH_VALUE *v, uint64_t timeStamp, double dataPoint); diff --git a/aqhome/msg/ipc/data/m_ipcd_setdata.c b/aqhome/msg/ipc/data/m_ipcd_setdata.c index 63b71a5..ea0f85b 100644 --- a/aqhome/msg/ipc/data/m_ipcd_setdata.c +++ b/aqhome/msg/ipc/data/m_ipcd_setdata.c @@ -37,7 +37,7 @@ AQH_MESSAGE *AQH_IpcdMessageSetData_new(uint16_t code, uint32_t msgId, uint32_t refMsgId, - const AQH_VALUE *value, const char *data) + const AQH_VALUE *value, double data) { AQH_MESSAGE *msg; GWEN_BUFFER *buf; @@ -51,8 +51,7 @@ AQH_MESSAGE *AQH_IpcdMessageSetData_new(uint16_t code, GWEN_Buffer_free(buf); return NULL; } - if (data && *data) - GWEN_Tag16_WriteStringTagToBuffer(AQH_MSGDATA_SET_TAGS_DATA, data, buf); + GWEN_Tag16_WriteDoubleTagToBuffer(AQH_MSGDATA_SET_TAGS_DATA, data, buf); msg=AQH_IpcMessage_new(AQH_IPC_PROTOCOL_DATA_ID, AQH_IPC_PROTOCOL_DATA_VERSION, code, msgId, refMsgId, GWEN_Buffer_GetUsedBytes(buf), (const uint8_t*) GWEN_Buffer_GetStart(buf)); @@ -78,9 +77,9 @@ AQH_VALUE *AQH_IpcdMessageSetData_ReadValue(const GWEN_TAG16_LIST *tagList) -char *AQH_IpcdMessageSetData_ReadData(const GWEN_TAG16_LIST *tagList) +double AQH_IpcdMessageSetData_ReadData(const GWEN_TAG16_LIST *tagList) { - return AQH_Tag16_GetTagDataAsNewString(tagList, AQH_MSGDATA_SET_TAGS_DATA, NULL); + return AQH_Tag16_GetTagDataAsDouble(tagList, AQH_MSGDATA_SET_TAGS_DATA, 0.0); } @@ -92,16 +91,16 @@ void AQH_IpcdMessageSetData_DumpToBuffer(const AQH_MESSAGE *msg, const GWEN_TAG1 const char *valueName; const char *valueUnits; int valueType; - char *data; + double data; value=tagList?AQH_IpcdMessageSetData_ReadValue(tagList):NULL; valueName=value?AQH_Value_GetNameForSystem(value):NULL; valueUnits=value?AQH_Value_GetValueUnits(value):NULL; valueType=value?AQH_Value_GetValueType(value):0; - data=tagList?AQH_IpcdMessageSetData_ReadData(tagList):NULL; + data=tagList?AQH_IpcdMessageSetData_ReadData(tagList):0.0; GWEN_Buffer_AppendArgs(dbuf, - "SETDATA(%s) %s (code=%d, proto=%d, proto version=%d, name=%s, units=%s, type=%d, value=%s)\n", + "SETDATA(%s) %s (code=%d, proto=%d, proto version=%d, name=%s, units=%s, type=%d, value=%.2f)\n", AQH_IpcdMessage_MsgTypeToChar(AQH_IpcMessage_GetCode(msg)), sText?sText:"", AQH_IpcMessage_GetCode(msg), @@ -110,8 +109,7 @@ void AQH_IpcdMessageSetData_DumpToBuffer(const AQH_MESSAGE *msg, const GWEN_TAG1 valueName?valueName:"", valueUnits?valueUnits:"", valueType, - data?data:""); - free(data); + data); AQH_Value_free(value); } diff --git a/aqhome/msg/ipc/data/m_ipcd_setdata.h b/aqhome/msg/ipc/data/m_ipcd_setdata.h index 3aee4ba..c6c28d3 100644 --- a/aqhome/msg/ipc/data/m_ipcd_setdata.h +++ b/aqhome/msg/ipc/data/m_ipcd_setdata.h @@ -27,10 +27,10 @@ AQHOME_API AQH_MESSAGE *AQH_IpcdMessageSetData_new(uint16_t code, uint32_t msgId, uint32_t refMsgId, - const AQH_VALUE *value, const char *data); + const AQH_VALUE *value, double data); AQHOME_API AQH_VALUE *AQH_IpcdMessageSetData_ReadValue(const GWEN_TAG16_LIST *tagList); -AQHOME_API char *AQH_IpcdMessageSetData_ReadData(const GWEN_TAG16_LIST *tagList); +AQHOME_API double AQH_IpcdMessageSetData_ReadData(const GWEN_TAG16_LIST *tagList); AQHOME_API void AQH_IpcdMessageSetData_DumpToBuffer(const AQH_MESSAGE *msg, const GWEN_TAG16_LIST *tagList, GWEN_BUFFER *dbuf, const char *sText); diff --git a/aqhome/msg/ipc/m_ipc_tag16.c b/aqhome/msg/ipc/m_ipc_tag16.c index a7a2e6d..f151e75 100644 --- a/aqhome/msg/ipc/m_ipc_tag16.c +++ b/aqhome/msg/ipc/m_ipc_tag16.c @@ -161,6 +161,19 @@ uint64_t AQH_Tag16_GetTagDataAsUint64(const GWEN_TAG16_LIST *tagList, unsigned i +double AQH_Tag16_GetTagDataAsDouble(const GWEN_TAG16_LIST *tagList, unsigned int tagType, double defaultValue) +{ + if (tagList) { + const GWEN_TAG16 *tag; + + tag=GWEN_Tag16_List_FindFirstByTagType(tagList, tagType); + return tag?GWEN_Tag16_GetTagDataAsDouble(tag, defaultValue):defaultValue; + } + return defaultValue; +} + + + int AQH_Tag16_WriteValueListAsTagsToBuffer(unsigned int tagType, const AQH_VALUE_LIST *valueList, GWEN_BUFFER *buf) { if (valueList) { diff --git a/aqhome/msg/ipc/m_ipc_tag16.h b/aqhome/msg/ipc/m_ipc_tag16.h index 044169a..1df64b3 100644 --- a/aqhome/msg/ipc/m_ipc_tag16.h +++ b/aqhome/msg/ipc/m_ipc_tag16.h @@ -27,6 +27,7 @@ AQHOME_API GWEN_TAG16_LIST *AQH_Tag16_ParseTags(const uint8_t *payloadPtr, uint3 AQHOME_API char *AQH_Tag16_GetTagDataAsNewString(const GWEN_TAG16_LIST *tagList, unsigned int tagType, const char *defaultValue); AQHOME_API uint32_t AQH_Tag16_GetTagDataAsUint32(const GWEN_TAG16_LIST *tagList, unsigned int tagType, uint32_t defaultValue); AQHOME_API uint64_t AQH_Tag16_GetTagDataAsUint64(const GWEN_TAG16_LIST *tagList, unsigned int tagType, uint64_t defaultValue); +AQHOME_API double AQH_Tag16_GetTagDataAsDouble(const GWEN_TAG16_LIST *tagList, unsigned int tagType, double defaultValue); /* utils */ AQHOME_API int AQH_Tag16_WriteValueListAsTagsToBuffer(unsigned int tagType, const AQH_VALUE_LIST *valueList, GWEN_BUFFER *buf); diff --git a/devices/mqtt/tasmota_plug.xml b/devices/mqtt/tasmota_plug.xml index b6b4e49..cb53d46 100644 --- a/devices/mqtt/tasmota_plug.xml +++ b/devices/mqtt/tasmota_plug.xml @@ -27,8 +27,8 @@ - - + + diff --git a/devices/mqtt/tasmota_plug_old.xml b/devices/mqtt/tasmota_plug_old.xml index 7f7c708..f20d994 100644 --- a/devices/mqtt/tasmota_plug_old.xml +++ b/devices/mqtt/tasmota_plug_old.xml @@ -27,8 +27,8 @@ - - + +