From 7f9d4cd84c4e0aaf515d8ea73cafcf3bd9b8fda9 Mon Sep 17 00:00:00 2001 From: fengzero Date: Wed, 10 Aug 2022 09:42:50 +0000 Subject: [PATCH] feat(driver): set float precision --- Install-dependencies.md | 2 +- ft/resource/error.resource | 1 + include/neuron/define.h | 1 + include/neuron/errcodes.h | 1 + include/neuron/json/json.h | 1 + include/neuron/json/neu_json_rw.h | 1 + include/neuron/tag.h | 1 + include/neuron/type.h | 3 +- install.sh | 2 +- persistence/0000_2.1.0_initial.sql | 1 + ....2.0_remove_tag_name_unique_constraint.sql | 1 + plugins/modbus/modbus_req.c | 16 ++- plugins/modbus/modbus_stack.c | 9 +- plugins/mqtt/command/read_write.c | 1 + plugins/mqtt/mqtt_plugin.c | 2 +- plugins/restful/datatag_handle.c | 3 + plugins/restful/http.c | 4 + plugins/restful/rw_handle.c | 1 + src/adapter/driver/driver.c | 110 +++++++++++++----- src/base/group.c | 3 + src/base/tag.c | 1 + src/parser/neu_json_rw.c | 14 ++- src/parser/neu_json_tag.c | 21 +++- src/parser/neu_json_tag.h | 3 + src/persist/persist.c | 31 ++--- src/utils/json.c | 10 +- tests/json_test.cc | 5 +- 27 files changed, 182 insertions(+), 67 deletions(-) diff --git a/Install-dependencies.md b/Install-dependencies.md index 0f12df1f..58a910ca 100644 --- a/Install-dependencies.md +++ b/Install-dependencies.md @@ -14,7 +14,7 @@ $ make && sudo make install [jansson](https://github.com/akheron/jansson) ```shell -$ git clone -b v2.14 https://github.com/akheron/jansson.git +$ git clone https://github.com/neugates/jansson.git $ cd jansson && mkdir build && cd build $ cmake -DJANSSON_BUILD_DOCS=OFF -DJANSSON_EXAMPLES=OFF ..&& make && sudo make install ``` diff --git a/ft/resource/error.resource b/ft/resource/error.resource index 12181959..37c44265 100644 --- a/ft/resource/error.resource +++ b/ft/resource/error.resource @@ -39,6 +39,7 @@ ${NEU_ERR_TAG_ADDRESS_FORMAT_INVALID} 2205 ${NEU_ERR_TAG_NAME_TOO_LONG} 2206 ${NEU_ERR_TAG_ADDRESS_TOO_LONG} 2207 ${NEU_ERR_TAG_DESCRIPTION_TOO_LONG} 2208 +${NEU_ERR_TAG_PRECISION_INVALID} 2209 ${NEU_ERR_LIBRARY_NOT_FOUND} 2301 ${NEU_ERR_LIBRARY_INFO_INVALID} 2302 diff --git a/include/neuron/define.h b/include/neuron/define.h index 539c5f3f..d939b79e 100644 --- a/include/neuron/define.h +++ b/include/neuron/define.h @@ -31,6 +31,7 @@ #define NEU_PLUGIN_DESCRIPTION_LEN 512 #define NEU_DRIVER_TAG_CACHE_EXPIRE_TIME 30 #define NEU_APP_SUBSCRIBE_MSG_SIZE 4 +#define NEU_TAG_FLOAG_PRECISION_MAX 17 typedef enum neu_plugin_kind { NEU_PLUGIN_KIND_STATIC = 0, diff --git a/include/neuron/errcodes.h b/include/neuron/errcodes.h index c8b04ba1..34587514 100644 --- a/include/neuron/errcodes.h +++ b/include/neuron/errcodes.h @@ -69,6 +69,7 @@ typedef enum { NEU_ERR_TAG_NAME_TOO_LONG = 2206, NEU_ERR_TAG_ADDRESS_TOO_LONG = 2207, NEU_ERR_TAG_DESCRIPTION_TOO_LONG = 2208, + NEU_ERR_TAG_PRECISION_INVALID = 2209, NEU_ERR_LIBRARY_NOT_FOUND = 2301, NEU_ERR_LIBRARY_INFO_INVALID = 2302, diff --git a/include/neuron/json/json.h b/include/neuron/json/json.h index ffd18fe1..ba04eccd 100644 --- a/include/neuron/json/json.h +++ b/include/neuron/json/json.h @@ -60,6 +60,7 @@ typedef struct neu_json_elem { char * name; enum neu_json_type t; union neu_json_value v; + uint8_t precision; } neu_json_elem_t; #define NEU_JSON_ELEM_SIZE(elems) sizeof(elems) / sizeof(neu_json_elem_t) diff --git a/include/neuron/json/neu_json_rw.h b/include/neuron/json/neu_json_rw.h index 16a08c5a..24a79bc3 100644 --- a/include/neuron/json/neu_json_rw.h +++ b/include/neuron/json/neu_json_rw.h @@ -42,6 +42,7 @@ typedef struct { char * name; enum neu_json_type t; union neu_json_value value; + uint8_t precision; } neu_json_read_resp_tag_t; typedef struct { diff --git a/include/neuron/tag.h b/include/neuron/tag.h index 9fd79b9c..a94f251f 100644 --- a/include/neuron/tag.h +++ b/include/neuron/tag.h @@ -75,6 +75,7 @@ typedef struct { char * description; neu_attribute_e attribute; neu_type_e type; + uint8_t precision; neu_datatag_addr_option_u option; uint8_t meta[NEU_TAG_META_SIZE]; } neu_datatag_t; diff --git a/include/neuron/type.h b/include/neuron/type.h index 413ee11b..bbfc0811 100644 --- a/include/neuron/type.h +++ b/include/neuron/type.h @@ -67,7 +67,7 @@ inline static const char *neu_type_string(neu_type_e type) case NEU_TYPE_UINT64: return "NEU_TYPE_UINT64"; case NEU_TYPE_FLOAT: - return "NEU_TYPE_FLOAt"; + return "NEU_TYPE_FLOAT"; case NEU_TYPE_DOUBLE: return "NEU_TYPE_DOUBLE"; case NEU_TYPE_BIT: @@ -105,6 +105,7 @@ typedef union { typedef struct { neu_type_e type; neu_value_u value; + uint8_t precision; } neu_dvalue_t; typedef union neu_value8 { uint8_t value; diff --git a/install.sh b/install.sh index 1188dbc1..1738718d 100755 --- a/install.sh +++ b/install.sh @@ -89,7 +89,7 @@ function build_sqlite3() { } build_zlog -compile_source akheron/jansson.git v2.14 "-DJANSSON_BUILD_DOCS=OFF -DJANSSON_EXAMPLES=OFF" +compile_source neugates/jansson.git HEAD "-DJANSSON_BUILD_DOCS=OFF -DJANSSON_EXAMPLES=OFF" build_openssl compile_source neugates/nng.git HEAD "-DBUILD_SHARED_LIBS=OFF -DNNG_TESTS=OFF" compile_source benmcollins/libjwt.git v1.13.1 "-DENABLE_PIC=ON -DBUILD_SHARED_LIBS=OFF" diff --git a/persistence/0000_2.1.0_initial.sql b/persistence/0000_2.1.0_initial.sql index 35393b5d..bf4cb718 100644 --- a/persistence/0000_2.1.0_initial.sql +++ b/persistence/0000_2.1.0_initial.sql @@ -56,6 +56,7 @@ CREATE TABLE IF NOT EXISTS name NOT NULL UNIQUE check(length(name) <= 32), address NOT NULL check(length(address) <= 64), attribute INTEGER NOT NULL check(attribute BETWEEN 0 AND 7), + precision INTEGER NOT NULL check(precision BETWEEN 0 AND 17), type INTEGER NOT NULL check(type BETWEEN 0 AND 15), description NOT NULL check(length(description) <= 128), UNIQUE (driver_name, group_name, name), diff --git a/persistence/0001_2.2.0_remove_tag_name_unique_constraint.sql b/persistence/0001_2.2.0_remove_tag_name_unique_constraint.sql index 8c2dd13d..ad3d5a07 100644 --- a/persistence/0001_2.2.0_remove_tag_name_unique_constraint.sql +++ b/persistence/0001_2.2.0_remove_tag_name_unique_constraint.sql @@ -29,6 +29,7 @@ CREATE TABLE name NOT NULL check(length(name) <= 32), address NOT NULL check(length(address) <= 64), attribute INTEGER NOT NULL check(attribute BETWEEN 0 AND 7), + precision INTEGER NOT NULL check(precision BETWEEN 0 AND 17), TYPE INTEGER NOT NULL check(TYPE BETWEEN 0 AND 15), description NOT NULL check(length(description) <= 128), UNIQUE (driver_name, group_name, name), diff --git a/plugins/modbus/modbus_req.c b/plugins/modbus/modbus_req.c index 5ce240a4..74efe9e4 100644 --- a/plugins/modbus/modbus_req.c +++ b/plugins/modbus/modbus_req.c @@ -79,16 +79,16 @@ int modbus_group_timer(neu_plugin_t *plugin, neu_plugin_group_t *group, } else { struct modbus_group_data *gd = (struct modbus_group_data *) group->user_data; + plugin->plugin_group_data = gd; for (uint16_t i = 0; i < gd->cmd_sort->n_cmd; i++) { uint16_t response_size = 0; - int ret = modbus_stack_read( + plugin->cmd_idx = i; + int ret = modbus_stack_read( plugin->stack, gd->cmd_sort->cmd[i].slave_id, gd->cmd_sort->cmd[i].area, gd->cmd_sort->cmd[i].start_address, gd->cmd_sort->cmd[i].n_register, &response_size); if (ret > 0) { - plugin->plugin_group_data = gd; - plugin->cmd_idx = i; process_protocol_buf(plugin, response_size); } } @@ -106,6 +106,16 @@ int modbus_value_handle(void *ctx, uint8_t slave_id, uint16_t n_byte, uint16_t start_address = gd->cmd_sort->cmd[plugin->cmd_idx].start_address; uint16_t n_register = gd->cmd_sort->cmd[plugin->cmd_idx].n_register; + if (bytes == NULL) { + neu_dvalue_t dvalue = { 0 }; + + dvalue.type = NEU_TYPE_ERROR; + dvalue.value.i32 = NEU_ERR_PLUGIN_DISCONNECTED; + plugin->common.adapter_callbacks->driver.update( + plugin->common.adapter, gd->group, NULL, dvalue); + return 0; + } + utarray_foreach(gd->cmd_sort->cmd[plugin->cmd_idx].tags, modbus_point_t **, p_tag) { diff --git a/plugins/modbus/modbus_stack.c b/plugins/modbus/modbus_stack.c index 4cee71f4..ede09346 100644 --- a/plugins/modbus/modbus_stack.c +++ b/plugins/modbus/modbus_stack.c @@ -104,6 +104,7 @@ int modbus_stack_read(modbus_stack_t *stack, uint8_t slave_id, { static __thread uint8_t buf[16] = { 0 }; static __thread neu_protocol_pack_buf_t pbuf = { 0 }; + int ret = 0; neu_protocol_pack_buf_init(&pbuf, buf, sizeof(buf)); @@ -134,8 +135,12 @@ int modbus_stack_read(modbus_stack_t *stack, uint8_t slave_id, modbus_header_wrap(&pbuf, stack->seq++); *response_size += sizeof(struct modbus_header); - return stack->send_fn(stack->ctx, neu_protocol_pack_buf_used_size(&pbuf), - neu_protocol_pack_buf_get(&pbuf)); + ret = stack->send_fn(stack->ctx, neu_protocol_pack_buf_used_size(&pbuf), + neu_protocol_pack_buf_get(&pbuf)); + if (ret <= 0) { + stack->value_fn(stack->ctx, 0, 0, NULL); + } + return ret; } int modbus_stack_write(modbus_stack_t *stack, void *req, uint8_t slave_id, diff --git a/plugins/mqtt/command/read_write.c b/plugins/mqtt/command/read_write.c index b251415d..fff50787 100644 --- a/plugins/mqtt/command/read_write.c +++ b/plugins/mqtt/command/read_write.c @@ -107,6 +107,7 @@ static void wrap_read_response_json(neu_resp_tag_value_t *tags, uint16_t len, case NEU_TYPE_FLOAT: json->tags[i].t = NEU_JSON_FLOAT; json->tags[i].value.val_float = tag->value.value.f32; + json->tags[i].precision = tag->value.precision; break; case NEU_TYPE_DOUBLE: json->tags[i].t = NEU_JSON_DOUBLE; diff --git a/plugins/mqtt/mqtt_plugin.c b/plugins/mqtt/mqtt_plugin.c index 033f2e24..6c940800 100644 --- a/plugins/mqtt/mqtt_plugin.c +++ b/plugins/mqtt/mqtt_plugin.c @@ -706,7 +706,7 @@ static int mqtt_plugin_request(neu_plugin_t *plugin, neu_reqresp_head_t *head, neu_reqresp_nodes_state_t *states = (neu_reqresp_nodes_state_t *) data; utarray_foreach(states->states, neu_nodes_state_t *, state) { - nlog_info("node %s: link: %d, running: %d", state->node, + plog_info(plugin, "node %s: link: %d, running: %d", state->node, state->state.link, state->state.running); } utarray_free(states->states); diff --git a/plugins/restful/datatag_handle.c b/plugins/restful/datatag_handle.c index 478a161f..7ce60840 100644 --- a/plugins/restful/datatag_handle.c +++ b/plugins/restful/datatag_handle.c @@ -50,6 +50,7 @@ void handle_add_tags(nng_aio *aio) for (int i = 0; i < req->n_tag; i++) { cmd.tags[i].attribute = req->tags[i].attribute; cmd.tags[i].type = req->tags[i].type; + cmd.tags[i].precision = req->tags[i].precision; cmd.tags[i].address = strdup(req->tags[i].address); cmd.tags[i].name = strdup(req->tags[i].name); if (req->tags[i].description != NULL) { @@ -132,6 +133,7 @@ void handle_update_tags(nng_aio *aio) for (int i = 0; i < req->n_tag; i++) { cmd.tags[i].attribute = req->tags[i].attribute; cmd.tags[i].type = req->tags[i].type; + cmd.tags[i].precision = req->tags[i].precision; cmd.tags[i].address = strdup(req->tags[i].address); cmd.tags[i].name = strdup(req->tags[i].name); if (req->tags[i].description != NULL) { @@ -211,6 +213,7 @@ void handle_get_tags_resp(nng_aio *aio, neu_resp_get_tag_t *tags) tags_res.tags[index].description = tag->description; tags_res.tags[index].type = tag->type; tags_res.tags[index].attribute = tag->attribute; + tags_res.tags[index].precision = tag->precision; } neu_json_encode_by_fn(&tags_res, neu_json_encode_get_tags_resp, &result); diff --git a/plugins/restful/http.c b/plugins/restful/http.c index fb068621..71ddddcb 100644 --- a/plugins/restful/http.c +++ b/plugins/restful/http.c @@ -341,6 +341,10 @@ int http_response(nng_aio *aio, neu_err_code_e code, char *content) case NEU_ERR_TAG_ATTRIBUTE_NOT_SUPPORT: case NEU_ERR_TAG_TYPE_NOT_SUPPORT: case NEU_ERR_TAG_ADDRESS_FORMAT_INVALID: + case NEU_ERR_TAG_DESCRIPTION_TOO_LONG: + case NEU_ERR_TAG_PRECISION_INVALID: + case NEU_ERR_TAG_NAME_TOO_LONG: + case NEU_ERR_TAG_ADDRESS_TOO_LONG: status = NNG_HTTP_STATUS_PARTIAL_CONTENT; break; default: diff --git a/plugins/restful/rw_handle.c b/plugins/restful/rw_handle.c index 370be875..eaad7c2f 100644 --- a/plugins/restful/rw_handle.c +++ b/plugins/restful/rw_handle.c @@ -148,6 +148,7 @@ void handle_read_resp(nng_aio *aio, neu_resp_read_group_t *resp) case NEU_TYPE_FLOAT: api_res.tags[i].t = NEU_JSON_FLOAT; api_res.tags[i].value.val_float = resp->tags[i].value.value.f32; + api_res.tags[i].precision = resp->tags[i].value.precision; break; case NEU_TYPE_DOUBLE: api_res.tags[i].t = NEU_JSON_DOUBLE; diff --git a/src/adapter/driver/driver.c b/src/adapter/driver/driver.c index 4e40f341..24d04adf 100644 --- a/src/adapter/driver/driver.c +++ b/src/adapter/driver/driver.c @@ -62,9 +62,11 @@ struct neu_adapter_driver { static int report_callback(void *usr_data); static int read_callback(void *usr_data); static void read_group(int64_t timestamp, int64_t timeout, - neu_driver_cache_t *cache, bool report, - const char *group, UT_array *tags, - neu_resp_tag_value_t *datas); + neu_driver_cache_t *cache, const char *group, + UT_array *tags, neu_resp_tag_value_t *datas); +static int read_report_group(int64_t timestamp, int64_t timeout, + neu_driver_cache_t *cache, const char *group, + UT_array *tags, neu_resp_tag_value_t *datas); static void update(neu_adapter_t *adapter, const char *group, const char *tag, neu_dvalue_t value); static void write_response(neu_adapter_t *adapter, void *r, neu_error error); @@ -242,7 +244,7 @@ void neu_adapter_driver_read_group(neu_adapter_driver_t *driver, read_group(driver->adapter.timestamp, neu_group_get_interval(group) * NEU_DRIVER_TAG_CACHE_EXPIRE_TIME, - driver->cache, false, cmd->group, tags, resp.tags); + driver->cache, cmd->group, tags, resp.tags); } strcpy(resp.driver, cmd->driver); @@ -466,6 +468,10 @@ int neu_adapter_driver_add_tag(neu_adapter_driver_t *driver, const char *group, return NEU_ERR_TAG_DESCRIPTION_TOO_LONG; } + if (tag->precision > NEU_TAG_FLOAG_PRECISION_MAX) { + return NEU_ERR_TAG_PRECISION_INVALID; + } + ret = driver->adapter.module->intf_funs->driver.validate_tag( driver->adapter.plugin, tag); if (ret != NEU_ERR_SUCCESS) { @@ -524,6 +530,10 @@ int neu_adapter_driver_update_tag(neu_adapter_driver_t *driver, return NEU_ERR_TAG_DESCRIPTION_TOO_LONG; } + if (tag->precision > NEU_TAG_FLOAG_PRECISION_MAX) { + return NEU_ERR_TAG_PRECISION_INVALID; + } + ret = driver->adapter.module->intf_funs->driver.validate_tag( driver->adapter.plugin, tag); if (ret != NEU_ERR_SUCCESS) { @@ -591,15 +601,16 @@ static int report_callback(void *usr_data) strcpy(data->driver, group->driver->adapter.name); strcpy(data->group, group->name); - data->n_tag = utarray_len(tags); - read_group(group->driver->adapter.timestamp, - neu_group_get_interval(group->group) * - NEU_DRIVER_TAG_CACHE_EXPIRE_TIME, - group->driver->cache, true, group->name, tags, - (neu_resp_tag_value_t *) &data[1]); + data->n_tag = read_report_group(group->driver->adapter.timestamp, + neu_group_get_interval(group->group) * + NEU_DRIVER_TAG_CACHE_EXPIRE_TIME, + group->driver->cache, group->name, tags, + (neu_resp_tag_value_t *) &data[1]); - group->driver->adapter.cb_funs.response(&group->driver->adapter, &header, - data); + if (data->n_tag > 0) { + group->driver->adapter.cb_funs.response(&group->driver->adapter, + &header, data); + } utarray_free(tags); free(data); return 0; @@ -658,10 +669,57 @@ static int read_callback(void *usr_data) return 0; } +static int read_report_group(int64_t timestamp, int64_t timeout, + neu_driver_cache_t *cache, const char *group, + UT_array *tags, neu_resp_tag_value_t *datas) +{ + int index = 0; + + utarray_foreach(tags, neu_datatag_t *, tag) + { + neu_driver_cache_value_t value = { 0 }; + + if (neu_tag_attribute_test(tag, NEU_ATTRIBUTE_SUBSCRIBE)) { + if (neu_driver_cache_get_changed(cache, group, tag->name, &value) != + 0) { + nlog_debug("tag: %s not changed", tag->name); + continue; + } + } else { + if (neu_driver_cache_get(cache, group, tag->name, &value) != 0) { + strcpy(datas[index].tag, tag->name); + datas[index].value.type = NEU_TYPE_ERROR; + datas[index].value.value.i32 = NEU_ERR_PLUGIN_TAG_NOT_READY; + index += 1; + continue; + } + } + strcpy(datas[index].tag, tag->name); + + if (value.error != 0) { + datas[index].value.type = NEU_TYPE_ERROR; + datas[index].value.value.i32 = value.error; + index += 1; + continue; + } + + if ((timestamp - value.timestamp) > timeout) { + datas[index].value.type = NEU_TYPE_ERROR; + datas[index].value.value.i32 = NEU_ERR_PLUGIN_TAG_VALUE_EXPIRED; + } else { + datas[index].value.type = tag->type; + datas[index].value.value = value.value; + datas[index].value.precision = tag->precision; + } + index += 1; + } + + return index; +} + static void read_group(int64_t timestamp, int64_t timeout, - neu_driver_cache_t *cache, bool report, - const char *group, UT_array *tags, - neu_resp_tag_value_t *datas) + neu_driver_cache_t *cache, const char *group, + UT_array *tags, neu_resp_tag_value_t *datas) { utarray_foreach(tags, neu_datatag_t *, tag) { @@ -670,19 +728,10 @@ static void read_group(int64_t timestamp, int64_t timeout, strcpy(datas[index].tag, tag->name); - if (report && neu_tag_attribute_test(tag, NEU_ATTRIBUTE_SUBSCRIBE)) { - if (neu_driver_cache_get_changed(cache, group, tag->name, &value) != - 0) { - datas[index].value.type = NEU_TYPE_ERROR; - datas[index].value.value.i32 = NEU_ERR_PLUGIN_TAG_NOT_READY; - continue; - } - } else { - if (neu_driver_cache_get(cache, group, tag->name, &value) != 0) { - datas[index].value.type = NEU_TYPE_ERROR; - datas[index].value.value.i32 = NEU_ERR_PLUGIN_TAG_NOT_READY; - continue; - } + if (neu_driver_cache_get(cache, group, tag->name, &value) != 0) { + datas[index].value.type = NEU_TYPE_ERROR; + datas[index].value.value.i32 = NEU_ERR_PLUGIN_TAG_NOT_READY; + continue; } if (value.error != 0) { @@ -695,8 +744,9 @@ static void read_group(int64_t timestamp, int64_t timeout, datas[index].value.type = NEU_TYPE_ERROR; datas[index].value.value.i32 = NEU_ERR_PLUGIN_TAG_VALUE_EXPIRED; } else { - datas[index].value.type = tag->type; - datas[index].value.value = value.value; + datas[index].value.type = tag->type; + datas[index].value.value = value.value; + datas[index].value.precision = tag->precision; } } } diff --git a/src/base/group.c b/src/base/group.c index a5bea024..49757f61 100644 --- a/src/base/group.c +++ b/src/base/group.c @@ -119,6 +119,7 @@ int neu_group_add_tag(neu_group_t *group, neu_datatag_t *tag) el->tag->description = strdup(tag->description); el->tag->type = tag->type; el->tag->attribute = tag->attribute; + el->tag->precision = tag->precision; el->tag->option = tag->option; memcpy(el->tag->meta, tag->meta, sizeof(tag->meta)); @@ -151,6 +152,7 @@ int neu_group_update_tag(neu_group_t *group, neu_datatag_t *tag) el->tag->description = strdup(tag->description); el->tag->type = tag->type; el->tag->attribute = tag->attribute; + el->tag->precision = tag->precision; el->tag->option = tag->option; memcpy(el->tag->meta, tag->meta, sizeof(tag->meta)); @@ -221,6 +223,7 @@ neu_datatag_t *neu_group_find_tag(neu_group_t *group, const char *tag) result = calloc(1, sizeof(neu_datatag_t)); result->type = find->tag->type; result->attribute = find->tag->attribute; + result->precision = find->tag->precision; result->name = strdup(find->tag->name); result->address = strdup(find->tag->address); result->description = strdup(find->tag->description); diff --git a/src/base/tag.c b/src/base/tag.c index 0f6570b1..b68add55 100644 --- a/src/base/tag.c +++ b/src/base/tag.c @@ -31,6 +31,7 @@ static void tag_array_copy(void *_dst, const void *_src) dst->type = src->type; dst->attribute = src->attribute; + dst->precision = src->precision; dst->option = src->option; memcpy(dst->meta, src->meta, sizeof(src->meta)); dst->address = strdup(src->address); diff --git a/src/parser/neu_json_rw.c b/src/parser/neu_json_rw.c index 7e624b0e..8afce173 100644 --- a/src/parser/neu_json_rw.c +++ b/src/parser/neu_json_rw.c @@ -48,9 +48,10 @@ int neu_json_encode_read_resp(void *json_object, void *param) tag_elems[1].t = NEU_JSON_INT; tag_elems[1].v.val_int = p_tag->error; } else { - tag_elems[1].name = "value"; - tag_elems[1].t = p_tag->t; - tag_elems[1].v = p_tag->value; + tag_elems[1].name = "value"; + tag_elems[1].t = p_tag->t; + tag_elems[1].v = p_tag->value; + tag_elems[1].precision = p_tag->precision; } tag_array = neu_json_encode_array(tag_array, tag_elems, @@ -81,9 +82,10 @@ int neu_json_encode_read_resp1(void *json_object, void *param) neu_json_elem_t tag_elem = { 0 }; if (p_tag->error == 0) { - tag_elem.name = p_tag->name; - tag_elem.t = p_tag->t; - tag_elem.v = p_tag->value; + tag_elem.name = p_tag->name; + tag_elem.t = p_tag->t; + tag_elem.v = p_tag->value; + tag_elem.precision = p_tag->precision; neu_json_encode_field(values, &tag_elem, 1); } else { tag_elem.name = p_tag->name; diff --git a/src/parser/neu_json_tag.c b/src/parser/neu_json_tag.c index a0103bed..4d963e8c 100644 --- a/src/parser/neu_json_tag.c +++ b/src/parser/neu_json_tag.c @@ -82,6 +82,11 @@ int neu_json_decode_add_tags_req(char *buf, neu_json_add_tags_req_t **result) .name = "address", .t = NEU_JSON_STR, }, + { + .name = "precision", + .t = NEU_JSON_INT, + .attribute = NEU_JSON_ATTRIBUTE_OPTIONAL, + }, { .name = "description", .t = NEU_JSON_STR, @@ -98,7 +103,8 @@ int neu_json_decode_add_tags_req(char *buf, neu_json_add_tags_req_t **result) p_tag->name = tag_elems[1].v.val_str; p_tag->attribute = tag_elems[2].v.val_int; p_tag->address = tag_elems[3].v.val_str; - p_tag->description = tag_elems[4].v.val_str; + p_tag->precision = tag_elems[4].v.val_int; + p_tag->description = tag_elems[5].v.val_str; p_tag++; } @@ -270,6 +276,11 @@ int neu_json_encode_get_tags_resp(void *json_object, void *param) .t = NEU_JSON_INT, .v.val_int = p_tag->attribute, }, + { + .name = "precision", + .t = NEU_JSON_INT, + .v.val_int = p_tag->precision, + }, { .name = "address", .t = NEU_JSON_STR, @@ -352,6 +363,11 @@ int neu_json_decode_update_tags_req(char * buf, .name = "address", .t = NEU_JSON_STR, }, + { + .name = "precision", + .t = NEU_JSON_INT, + .attribute = NEU_JSON_ATTRIBUTE_OPTIONAL, + }, { .name = "description", .t = NEU_JSON_STR, @@ -368,7 +384,8 @@ int neu_json_decode_update_tags_req(char * buf, p_tag->name = tag_elems[1].v.val_str; p_tag->attribute = tag_elems[2].v.val_int; p_tag->address = tag_elems[3].v.val_str; - p_tag->description = tag_elems[4].v.val_str; + p_tag->precision = tag_elems[4].v.val_int; + p_tag->description = tag_elems[5].v.val_str; p_tag++; } diff --git a/src/parser/neu_json_tag.h b/src/parser/neu_json_tag.h index 9a2ea6b2..64814ff2 100644 --- a/src/parser/neu_json_tag.h +++ b/src/parser/neu_json_tag.h @@ -37,6 +37,7 @@ typedef struct { char * description; int64_t type; int64_t attribute; + int64_t precision; } neu_json_add_tags_req_tag_t; typedef struct { @@ -74,6 +75,7 @@ typedef struct { char * description; int64_t type; int64_t attribute; + int64_t precision; } neu_json_get_tags_resp_tag_t; typedef struct { @@ -89,6 +91,7 @@ typedef struct { char * description; int64_t type; int64_t attribute; + int64_t precision; } neu_json_update_tags_req_tag_t; typedef struct { diff --git a/src/persist/persist.c b/src/persist/persist.c index 200a30b2..244c6b57 100644 --- a/src/persist/persist.c +++ b/src/persist/persist.c @@ -832,18 +832,20 @@ int neu_persister_store_tag(neu_persister_t *persister, const char *driver_name, { return execute_sql( persister->db, - "INSERT INTO tags (driver_name, group_name, name, address, attribute, " - "type, description) VALUES(%Q, %Q, %Q, %Q, %i, %i, %Q)", + "INSERT INTO tags (driver_name, group_name, name, " + "address, attribute, precision, " + "type, description) VALUES(%Q, %Q, %Q, %Q, %i, %i, %i, %Q)", driver_name, group_name, tag->name, tag->address, tag->attribute, - tag->type, tag->description); + tag->precision, tag->type, tag->description); } int neu_persister_load_tags(neu_persister_t *persister, const char *driver_name, const char *group_name, UT_array **tags) { - sqlite3_stmt *stmt = NULL; - const char * query = "SELECT name, address, attribute, type, description " - "FROM tags WHERE driver_name=? AND group_name=?"; + sqlite3_stmt *stmt = NULL; + const char * query = + "SELECT name, address, attribute, precision, type, description " + "FROM tags WHERE driver_name=? AND group_name=?"; utarray_new(*tags, neu_tag_get_icd()); @@ -872,8 +874,9 @@ int neu_persister_load_tags(neu_persister_t *persister, const char *driver_name, .name = (char *) sqlite3_column_text(stmt, 0), .address = (char *) sqlite3_column_text(stmt, 1), .attribute = sqlite3_column_int(stmt, 2), - .type = sqlite3_column_int(stmt, 3), - .description = (char *) sqlite3_column_text(stmt, 4), + .precision = sqlite3_column_int64(stmt, 3), + .type = sqlite3_column_int(stmt, 4), + .description = (char *) sqlite3_column_text(stmt, 5), }; utarray_push_back(*tags, &tag); @@ -898,12 +901,12 @@ int neu_persister_update_tag(neu_persister_t *persister, const char *driver_name, const char *group_name, const neu_datatag_t *tag) { - return execute_sql( - persister->db, - "UPDATE tags SET address=%Q, attribute=%i, type=%i, description=%Q " - "WHERE driver_name=%Q AND group_name=%Q AND name=%Q", - tag->address, tag->attribute, tag->type, tag->description, driver_name, - group_name, tag->name); + return execute_sql(persister->db, + "UPDATE tags SET address=%Q, attribute=%i, " + "precision=%i, type=%i, description=%Q " + "WHERE driver_name=%Q AND group_name=%Q AND name=%Q", + tag->address, tag->attribute, tag->precision, tag->type, + tag->description, driver_name, group_name, tag->name); } int neu_persister_delete_tag(neu_persister_t *persister, diff --git a/src/utils/json.c b/src/utils/json.c index 54412720..ac68a5fd 100644 --- a/src/utils/json.c +++ b/src/utils/json.c @@ -40,10 +40,10 @@ static json_t *encode_object_value(neu_json_elem_t *ele) ob = json_string(ele->v.val_str); break; case NEU_JSON_DOUBLE: - ob = json_real(ele->v.val_double); + ob = json_realp(ele->v.val_double, ele->precision); break; case NEU_JSON_FLOAT: - ob = json_real(ele->v.val_float); + ob = json_realp(ele->v.val_float, ele->precision); break; case NEU_JSON_BOOL: ob = json_boolean(ele->v.val_bool); @@ -70,10 +70,12 @@ static json_t *encode_object(json_t *object, neu_json_elem_t ele) json_object_set_new(ob, ele.name, json_string(ele.v.val_str)); break; case NEU_JSON_FLOAT: - json_object_set_new(ob, ele.name, json_real(ele.v.val_float)); + json_object_set_new(ob, ele.name, + json_realp(ele.v.val_float, ele.precision)); break; case NEU_JSON_DOUBLE: - json_object_set_new(ob, ele.name, json_real(ele.v.val_double)); + json_object_set_new(ob, ele.name, + json_realp(ele.v.val_double, ele.precision)); break; case NEU_JSON_BOOL: json_object_set_new(ob, ele.name, json_boolean(ele.v.val_bool)); diff --git a/tests/json_test.cc b/tests/json_test.cc index 2cdbcd77..ea140172 100644 --- a/tests/json_test.cc +++ b/tests/json_test.cc @@ -153,8 +153,9 @@ TEST(JsonTest, EncodeField) elems[2].name = (char *) "field3"; elems[2].t = NEU_JSON_INT; - elems[3].name = (char *) "field4"; - elems[3].t = NEU_JSON_DOUBLE; + elems[3].name = (char *) "field4"; + elems[3].t = NEU_JSON_DOUBLE; + elems[3].precision = 0; elems[4].name = (char *) "field5"; elems[4].t = NEU_JSON_STR;