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.
This commit is contained in:
@@ -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,"<form action=\"setdata.html\" method=\"post\">\n");
|
||||
GBAA(dbuf, "<input type=\"hidden\" name=\"device\" value=\"%s\">\n", sDeviceName);
|
||||
_writeValueListToTable(valueList, dbuf);
|
||||
_writeValueListToTable(dc, valueList, dbuf);
|
||||
|
||||
GBAS(dbuf,"<input type=\"submit\" name=\"action\" value=\"Send\"/>");
|
||||
GBAS(dbuf, "</form>\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, "<p>Error setting value for %s</p>", 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, "<td>");
|
||||
if (AQH_Value_GetValueType(value)==AQH_ValueType_Actor)
|
||||
_addValueActionToForm(value, dbuf);
|
||||
_addLastValueToForm(dc, value, dbuf);
|
||||
GBAS(dbuf, "</td>");
|
||||
|
||||
GBAA(dbuf, "</tr>\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, "<input type=\"color\" name=\"%s\" value=\"#%08x\"/>", sValueName, (unsigned int) u.f);
|
||||
break;
|
||||
case AQH_ValueModality_OnOff:
|
||||
GBAA(dbuf, "<select name=\"%s\">" "<option value=\"unchanged\" >unchanged</option>", sValueName);
|
||||
GBAA(dbuf, "<option value=\"off\" %s>off</option>", (intVal==0)?"selected":"");
|
||||
GBAA(dbuf, "<option value=\"on\" %s>on</option>", (intVal==1)?"selected":"");
|
||||
GBAS(dbuf, "</select>");
|
||||
break;
|
||||
case AQH_ValueModality_OnOffAuto:
|
||||
GBAA(dbuf, "<select name=\"%s\">" "<option value=\"unchanged\" >unchanged</option>", sValueName);
|
||||
GBAA(dbuf, "<option value=\"off\" %s>off</option>", (intVal==0)?"selected":"");
|
||||
GBAA(dbuf, "<option value=\"on\" %s>on</option>", (intVal==1)?"selected":"");
|
||||
GBAA(dbuf, "<option value=\"auto\" %s>auto</option>", (intVal==2)?"selected":"");
|
||||
GBAS(dbuf, "</select>");
|
||||
break;
|
||||
default:
|
||||
// GBAA(dbuf, "<input type=\"text\" name=\"%s\" value=\"%.2f\"/>", 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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:"<empty>");
|
||||
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:"<empty>");
|
||||
#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;
|
||||
|
||||
@@ -32,18 +32,18 @@
|
||||
|
||||
<members>
|
||||
|
||||
<member name="aqhValue" type="char_ptr" maxlen="128">
|
||||
<member name="aqhValue" type="int" maxlen="8">
|
||||
<default>0</default>
|
||||
<preset>0</preset>
|
||||
<access>public</access>
|
||||
<flags>own</flags>
|
||||
<flags>with_getByMember</flags>
|
||||
</member>
|
||||
|
||||
<member name="driverValue" type="char_ptr" maxlen="128">
|
||||
<default>0</default>
|
||||
<preset>0</preset>
|
||||
<access>public</access>
|
||||
<flags>own</flags>
|
||||
<flags>own with_getByMember</flags>
|
||||
</member>
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -26,15 +26,6 @@
|
||||
|
||||
<unit id="and1" type="and" />
|
||||
|
||||
<unit id="zeroPosNegString1" type="zeroPosNegString">
|
||||
<params>
|
||||
<param name="valueIfNegative">OFF</param>
|
||||
<param name="valueIfZero">OFF</param>
|
||||
<param name="valueIfPositive">ON</param>
|
||||
</params>
|
||||
</unit>
|
||||
|
||||
|
||||
<unit id="valueSetOutPlug1" type="valueSet">
|
||||
<params>
|
||||
<param name="valueName">mqtt/109C2F/power</param>
|
||||
@@ -49,7 +40,6 @@
|
||||
<link sourceUnit=".timer" sourcePort="output" targetUnit="suntime1" targetPort="timer" />
|
||||
<link sourceUnit="suntime1" sourcePort="output" targetUnit="and1" targetPort="input" />
|
||||
<link sourceUnit="delayedOff1" sourcePort="output" targetUnit="and1" targetPort="input" />
|
||||
<link sourceUnit="and1" sourcePort="output" targetUnit="zeroPosNegString1" targetPort="input" />
|
||||
<link sourceUnit="zeroPosNegString1" sourcePort="output" targetUnit="valueSetOutPlug1" targetPort="input" />
|
||||
<link sourceUnit="and1" sourcePort="output" targetUnit="valueSetOutPlug1" targetPort="input" />
|
||||
</links>
|
||||
</network>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
</inputPorts>
|
||||
|
||||
<outputPorts>
|
||||
<outputPort name="output" dataType="string" />
|
||||
<outputPort name="output" dataType="double" />
|
||||
</outputPorts>
|
||||
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user