1
0
Fork 0
mirror of https://git.rwth-aachen.de/acs/public/villas/node/ synced 2025-03-09 00:00:00 +01:00

finished NGSI node type for Arthur's and Mohsen's demo

This commit is contained in:
Steffen Vogel 2015-09-22 13:19:44 +02:00
parent bfb0221ccf
commit a0b9b56109
3 changed files with 78 additions and 24 deletions

View file

@ -126,6 +126,10 @@ int version_compare(struct version *a, struct version *b);
/** Parse a dotted version string. */
int version_parse(const char *s, struct version *v);
/** Format a struct timespec date similar to strftime() */
int strftimespec(char *s, uint max, const char *format, struct timespec *ts)
__attribute__ ((format(strftime, 3, 0)));
/** Check assertion and exit if failed. */
#define assert(exp) do { \
if (!EXPECT(exp, 0)) \

View file

@ -25,12 +25,27 @@ static json_t * json_uuid()
uuid_t uuid;
uuid_generate_time(uuid);
uuid_unparse(uuid, eid);
uuid_unparse_lower(uuid, eid);
return json_string(eid);
}
static json_t * json_lookup(json_t *array, const char *key, const char *needle)
static json_t * json_date(struct timespec *ts)
{
struct timespec tsp;
if (!ts) {
clock_gettime(CLOCK_REALTIME, &tsp);
ts = &tsp;
}
// Example: 2015-09-21T11:42:25+02:00
char date[64];
strftimespec(date, sizeof(date), "%FT%T%z", ts);
return json_string(date);
}
static json_t * json_lookup(json_t *array, char *key, char *needle)
{
size_t ind;
json_t *obj;
@ -78,12 +93,16 @@ static int ngsi_request(CURL *handle, json_t *content, json_t **response)
curl_easy_setopt(handle, CURLOPT_POSTFIELDSIZE, strlen(post));
curl_easy_setopt(handle, CURLOPT_POSTFIELDS, post);
debug(20, "Request to context broker:\n%s", post);
CURLcode ret = curl_easy_perform(handle);
if (ret)
error("HTTP request failed: %s", curl_easy_strerror(ret));
curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &code);
debug(20, "Response from context broker (code=%ld):\n%s", code, chunk.data);
json_error_t err;
json_t *resp = json_loads(chunk.data, 0, &err);
if (!resp)
@ -117,8 +136,7 @@ static json_t * ngsi_build_context(struct node *n, config_setting_t *mapping)
if (!stoken)
cerror(mapping, "Invalid token");
char eid[64], etype[64]; /* Entity */
char aname[64], atype[64]; /* Attribute */
char eid[64], etype[64], aname[64], atype[64];
if (sscanf(stoken, "%63[^().](%63[^().]).%63[^().](%63[^().])", eid, etype, aname, atype) != 4)
cerror(ctoken, "Invalid token: '%s'", stoken);
@ -138,26 +156,26 @@ static json_t * ngsi_build_context(struct node *n, config_setting_t *mapping)
json_object_set(entity, "attributes", attributes);
json_array_append(elements, entity);
}
else
else {
if (i->structure == NGSI_CHILDREN)
cerror(ctoken, "Duplicate mapping for index %u", j);
attributes = json_object_get(entity, "attributes");
}
/* Create attribute */
if (json_lookup(attributes, "name", aname))
cerror(ctoken, "Duplicated attribute '%s' in NGSI mapping of node '%s'", aname, n->name);
json_t *metadatas;
json_t *attribute = json_pack("{ s: s, s: s }",
json_t *attribute = json_pack("{ s: s, s: s, s: s }",
"name", aname,
"type", atype
"type", atype,
"value", "0"
);
metadatas = json_array();
json_object_set(attribute, "metadatas", metadatas);
if (!strcmp(atype, "float"))
json_object_set(attribute, "value", json_real(0));
else if (!strcmp(atype, "integer"))
json_object_set(attribute, "value", json_integer(0));
/* Metadata */
json_array_append(metadatas, json_pack("{ s: s, s: s, s: s }",
@ -170,18 +188,29 @@ static json_t * ngsi_build_context(struct node *n, config_setting_t *mapping)
"type", "integer",
"value", j
));
json_array_append(attributes, attribute);
if (i->structure == NGSI_CHILDREN) {
json_array_append(attributes, json_pack("{ s: s, s: s, s: s }",
"name", "parentId",
"type", "UUID",
"type", "uuid",
"value", eid
));
json_array_append(attributes, json_pack("{ s: s, s: s, s: s }",
"name", "source",
"type", "string",
"value", "measurement"
));
json_array_append(attributes, json_pack("{ s: s, s: s, s: o }",
"name", "timestamp",
"type", "date",
"value", json_date(NULL)
));
}
i->context_map[j] = json_object_get(attribute, "value");
json_array_append(attributes, attribute);
i->context_map[j] = attribute;
}
return root;
@ -263,6 +292,7 @@ int ngsi_open(struct node *n)
snprintf(buf, sizeof(buf), "%s/v1/updateContext", i->endpoint);
curl_easy_setopt(i->curl, CURLOPT_URL, buf);
curl_easy_setopt(i->curl, CURLOPT_TIMEOUT_MS, i->timeout * 1e3);
curl_easy_setopt(i->curl, CURLOPT_HTTPHEADER, i->headers);
@ -295,12 +325,20 @@ int ngsi_write(struct node *n, struct msg *pool, int poolsize, int first, int cn
/* Update context */
for (int j = 0; j < i->context_len; j++) {
json_t *value = i->context_map[j];
json_t *attribute = i->context_map[j];
json_t *value = json_object_get(attribute, "value");
json_t *metadatas = json_object_get(attribute, "metadatas");
if (json_is_integer(value))
json_integer_set(value, m->data[j].i);
else if (json_is_real(value))
json_real_set(value, m->data[j].f);
json_t *timestamp = json_lookup(metadatas, "name", "timestamp");
json_object_update(timestamp, json_pack("{ s: s, s: s, s: o }",
"name", "timestamp",
"type", "date",
"value", json_date(&MSG_TS(m))
));
char new[64];
snprintf(new, sizeof(new), "%f", m->data[j].f); /** @todo for now we only support floating point values */
json_string_set(value, new);
}
/* Update UUIDs for children structure */
@ -309,9 +347,11 @@ int ngsi_write(struct node *n, struct msg *pool, int poolsize, int first, int cn
size_t ind;
json_array_foreach(elements, ind, entity)
json_object_set(entity, "id", json_uuid());
json_object_set(i->context, "updateAction", json_string("APPEND"));
}
json_object_set(i->context, "updateAction", json_string("UPDATE"));
else
json_object_set(i->context, "updateAction", json_string("UPDATE"));
json_t *response;
int code = ngsi_request(i->curl, i->context, &response);

View file

@ -31,6 +31,16 @@ int version_compare(struct version *a, struct version *b) {
return major ? major : minor;
}
int strftimespec(char *s, uint max, const char *format, struct timespec *ts)
{
struct tm t;
if (localtime_r(&(ts->tv_sec), &t) == NULL)
return -1;
return strftime(s, max, format, &t);
}
double box_muller(float m, float s)
{
double x1, x2, y1;