mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-09 00:00:00 +01:00
remove auto signal type detection
This commit is contained in:
parent
b5f1beb125
commit
b7d0f174ca
24 changed files with 117 additions and 145 deletions
|
@ -26,6 +26,7 @@
|
|||
#include <villas/advio.h>
|
||||
#include <villas/common.h>
|
||||
#include <villas/node.h>
|
||||
#include <villas/signal.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -41,8 +42,7 @@ enum io_flags {
|
|||
IO_NONBLOCK = (1 << 9), /**< Dont block io_read() while waiting for new samples. */
|
||||
IO_NEWLINES = (1 << 10), /**< The samples of this format are newline delimited. */
|
||||
IO_DESTROY_SIGNALS = (1 << 11), /**< Signal descriptors are managed by this IO instance. Destroy them in io_destoy() */
|
||||
IO_HAS_BINARY_PAYLOAD = (1 << 12), /**< This IO instance en/decodes binary payloads. */
|
||||
IO_AUTO_DETECT_FORMAT = (1 << 13) /**< This IO instance supports format auto-detection during decoding. */
|
||||
IO_HAS_BINARY_PAYLOAD = (1 << 12) /**< This IO instance en/decodes binary payloads. */
|
||||
};
|
||||
|
||||
enum io_mode {
|
||||
|
@ -82,7 +82,7 @@ struct io {
|
|||
|
||||
int io_init(struct io *io, const struct format_type *fmt, struct vlist *signals, int flags);
|
||||
|
||||
int io_init_auto(struct io *io, const struct format_type *fmt, int len, int flags);
|
||||
int io_init2(struct io *io, const struct format_type *fmt, enum signal_type type, int len, int flags);
|
||||
|
||||
int io_destroy(struct io *io);
|
||||
|
||||
|
|
|
@ -77,8 +77,8 @@ enum iec61850_type {
|
|||
|
||||
struct iec61850_type_descriptor {
|
||||
const char *name;
|
||||
enum iec61850_type type;
|
||||
enum signal_type format;
|
||||
enum iec61850_type iec_type;
|
||||
enum signal_type type;
|
||||
unsigned size;
|
||||
bool publisher;
|
||||
bool subscriber;
|
||||
|
|
|
@ -55,11 +55,10 @@ union signal_data {
|
|||
|
||||
enum signal_type {
|
||||
SIGNAL_TYPE_INVALID = 0, /**< Signal type is invalid. */
|
||||
SIGNAL_TYPE_AUTO = 1, /**< Signal type is unknown. Attempt autodetection. */
|
||||
SIGNAL_TYPE_FLOAT = 2, /**< See signal_data::f */
|
||||
SIGNAL_TYPE_INTEGER = 3, /**< See signal_data::i */
|
||||
SIGNAL_TYPE_BOOLEAN = 4, /**< See signal_data::b */
|
||||
SIGNAL_TYPE_COMPLEX = 5 /**< See signal_data::z */
|
||||
SIGNAL_TYPE_FLOAT = 1, /**< See signal_data::f */
|
||||
SIGNAL_TYPE_INTEGER = 2, /**< See signal_data::i */
|
||||
SIGNAL_TYPE_BOOLEAN = 3, /**< See signal_data::b */
|
||||
SIGNAL_TYPE_COMPLEX = 4 /**< See signal_data::z */
|
||||
};
|
||||
|
||||
/** Signal descriptor.
|
||||
|
|
|
@ -77,7 +77,7 @@ static size_t csv_sscan_single(struct io *io, const char *buf, size_t len, struc
|
|||
{
|
||||
int ret, i = 0;
|
||||
const char *ptr = buf;
|
||||
char *end, *next;
|
||||
char *end;
|
||||
|
||||
smp->flags = 0;
|
||||
smp->signals = io->signals;
|
||||
|
@ -117,25 +117,6 @@ static size_t csv_sscan_single(struct io *io, const char *buf, size_t len, struc
|
|||
if (!sig)
|
||||
goto out;
|
||||
|
||||
/* Perform signal detection only once */
|
||||
if (sig->type == SIGNAL_TYPE_AUTO) {
|
||||
|
||||
/* Find end of the current column */
|
||||
next = strpbrk(ptr, ((char[]) { io->separator, io->delimiter, 0 }));
|
||||
if (next == NULL)
|
||||
goto out;
|
||||
|
||||
/* Copy value to temporary '\0' terminated buffer */
|
||||
size_t len = next - ptr;
|
||||
char val[len+1];
|
||||
strncpy(val, ptr, len);
|
||||
val[len] = '\0';
|
||||
|
||||
sig->type = signal_type_detect(val);
|
||||
|
||||
debug(LOG_IO | 5, "Learned data type for index %u: %s", i, signal_type_to_str(sig->type));
|
||||
}
|
||||
|
||||
ret = signal_data_parse_str(&smp->data[i], sig, ptr, &end);
|
||||
if (ret || end == ptr) /* There are no valid values anymore. */
|
||||
goto out;
|
||||
|
@ -222,7 +203,7 @@ static struct plugin p1 = {
|
|||
.sscan = csv_sscan,
|
||||
.header = csv_header,
|
||||
.size = 0,
|
||||
.flags = IO_NEWLINES | IO_AUTO_DETECT_FORMAT |
|
||||
.flags = IO_NEWLINES |
|
||||
SAMPLE_HAS_TS_ORIGIN | SAMPLE_HAS_SEQUENCE | SAMPLE_HAS_DATA,
|
||||
.separator = '\t'
|
||||
}
|
||||
|
@ -237,7 +218,7 @@ static struct plugin p2 = {
|
|||
.sscan = csv_sscan,
|
||||
.header = csv_header,
|
||||
.size = 0,
|
||||
.flags = IO_NEWLINES | IO_AUTO_DETECT_FORMAT |
|
||||
.flags = IO_NEWLINES |
|
||||
SAMPLE_HAS_TS_ORIGIN | SAMPLE_HAS_SEQUENCE | SAMPLE_HAS_DATA,
|
||||
.separator = ','
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ static enum signal_type json_detect_format(json_t *val)
|
|||
return SIGNAL_TYPE_COMPLEX; /* must be a complex number */
|
||||
|
||||
default:
|
||||
return SIGNAL_TYPE_AUTO;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -133,10 +133,7 @@ static int json_pack_sample(struct io *io, json_t **j, struct sample *smp)
|
|||
);
|
||||
break;
|
||||
|
||||
case SIGNAL_TYPE_INVALID:
|
||||
case SIGNAL_TYPE_AUTO:
|
||||
json_value = json_null(); /* Unknown type */
|
||||
break;
|
||||
case SIGNAL_TYPE_INVALID: { }
|
||||
}
|
||||
|
||||
json_array_append(json_data, json_value);
|
||||
|
@ -213,11 +210,7 @@ static int json_unpack_sample(struct io *io, json_t *json_smp, struct sample *sm
|
|||
return -1;
|
||||
|
||||
enum signal_type fmt = json_detect_format(json_value);
|
||||
if (sig->type == SIGNAL_TYPE_AUTO) {
|
||||
debug(LOG_IO | 5, "Learned data type for index %zu: %s", i, signal_type_to_str(fmt));
|
||||
sig->type = fmt;
|
||||
}
|
||||
else if (sig->type != fmt) {
|
||||
if (sig->type != fmt) {
|
||||
error("Received invalid data type in JSON payload: Received %s, expected %s for signal %s (index %zu).",
|
||||
signal_type_to_str(fmt), signal_type_to_str(sig->type), sig->name, i);
|
||||
return -2;
|
||||
|
@ -361,8 +354,7 @@ static struct plugin p = {
|
|||
.sprint = json_sprint,
|
||||
.size = 0,
|
||||
.delimiter = '\n',
|
||||
.flags = IO_AUTO_DETECT_FORMAT |
|
||||
SAMPLE_HAS_TS_ORIGIN | SAMPLE_HAS_SEQUENCE | SAMPLE_HAS_DATA
|
||||
.flags = SAMPLE_HAS_TS_ORIGIN | SAMPLE_HAS_SEQUENCE | SAMPLE_HAS_DATA
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -115,7 +115,6 @@ int protobuf_sprint(struct io *io, char *buf, size_t len, size_t *wbytes, struct
|
|||
pb_val->z->imag = cimag(smp->data[j].z);
|
||||
break;
|
||||
|
||||
case SIGNAL_TYPE_AUTO:
|
||||
case SIGNAL_TYPE_INVALID:
|
||||
pb_val->value_case = VILLAS__NODE__VALUE__VALUE__NOT_SET;
|
||||
break;
|
||||
|
@ -181,11 +180,7 @@ int protobuf_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, s
|
|||
if (!sig)
|
||||
return -1;
|
||||
|
||||
if (sig->type == SIGNAL_TYPE_AUTO) {
|
||||
debug(LOG_IO | 5, "Learned data type for index %u: %s", j, signal_type_to_str(fmt));
|
||||
sig->type = fmt;
|
||||
}
|
||||
else if (sig->type != fmt) {
|
||||
if (sig->type != fmt) {
|
||||
error("Received invalid data type in Protobuf payload: Received %s, expected %s for signal %s (index %u).",
|
||||
signal_type_to_str(fmt), signal_type_to_str(sig->type), sig->name, i);
|
||||
return -2;
|
||||
|
@ -231,9 +226,9 @@ static struct plugin p = {
|
|||
.description = "Google Protobuf",
|
||||
.type = PLUGIN_TYPE_FORMAT,
|
||||
.format = {
|
||||
.sprint = protobuf_sprint,
|
||||
.sscan = protobuf_sscan,
|
||||
.flags = IO_AUTO_DETECT_FORMAT | IO_HAS_BINARY_PAYLOAD |
|
||||
.sprint = protobuf_sprint,
|
||||
.sscan = protobuf_sscan,
|
||||
.flags = IO_HAS_BINARY_PAYLOAD |
|
||||
SAMPLE_HAS_TS_ORIGIN | SAMPLE_HAS_SEQUENCE | SAMPLE_HAS_DATA
|
||||
}
|
||||
};
|
||||
|
|
|
@ -182,7 +182,6 @@ int raw_sprint(struct io *io, char *buf, size_t len, size_t *wbytes, struct samp
|
|||
}
|
||||
break;
|
||||
|
||||
case SIGNAL_TYPE_AUTO:
|
||||
case SIGNAL_TYPE_INVALID:
|
||||
return -1;
|
||||
}
|
||||
|
@ -344,7 +343,6 @@ int raw_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, struct
|
|||
}
|
||||
break;
|
||||
|
||||
case SIGNAL_TYPE_AUTO:
|
||||
case SIGNAL_TYPE_INVALID:
|
||||
warning("Unsupported format in RAW payload");
|
||||
return -1;
|
||||
|
|
|
@ -75,7 +75,7 @@ static size_t villas_human_sprint_single(struct io *io, char *buf, size_t len, c
|
|||
static size_t villas_human_sscan_single(struct io *io, const char *buf, size_t len, struct sample *smp)
|
||||
{
|
||||
int ret;
|
||||
char *end, *next;
|
||||
char *end;
|
||||
const char *ptr = buf;
|
||||
|
||||
double offset = 0;
|
||||
|
@ -142,25 +142,6 @@ static size_t villas_human_sscan_single(struct io *io, const char *buf, size_t l
|
|||
if (!sig)
|
||||
goto out;
|
||||
|
||||
/* Perform signal detection only once */
|
||||
if (sig->type == SIGNAL_TYPE_AUTO) {
|
||||
|
||||
/* Find end of the current column */
|
||||
next = strpbrk(ptr, ((char[]) { io->separator, io->delimiter, 0 }));
|
||||
if (next == NULL)
|
||||
goto out;
|
||||
|
||||
/* Copy value to temporary '\0' terminated buffer */
|
||||
size_t len = next - ptr;
|
||||
char val[len+1];
|
||||
strncpy(val, ptr, len);
|
||||
val[len] = '\0';
|
||||
|
||||
sig->type = signal_type_detect(val);
|
||||
|
||||
debug(LOG_IO | 5, "Learned data type for index %u: %s", i, signal_type_to_str(sig->type));
|
||||
}
|
||||
|
||||
ret = signal_data_parse_str(&smp->data[i], sig, ptr, &end);
|
||||
if (ret || end == ptr) /* There are no valid values anymore. */
|
||||
goto out;
|
||||
|
@ -252,8 +233,7 @@ static struct plugin p = {
|
|||
.sscan = villas_human_sscan,
|
||||
.header = villas_human_header,
|
||||
.size = 0,
|
||||
.flags = IO_NEWLINES | IO_AUTO_DETECT_FORMAT |
|
||||
SAMPLE_HAS_TS_ORIGIN | SAMPLE_HAS_SEQUENCE | SAMPLE_HAS_DATA,
|
||||
.flags = IO_NEWLINES | SAMPLE_HAS_TS_ORIGIN | SAMPLE_HAS_SEQUENCE | SAMPLE_HAS_DATA,
|
||||
.separator = '\t',
|
||||
.delimiter = '\n'
|
||||
}
|
||||
|
|
|
@ -160,7 +160,6 @@ static int average_process(struct hook *h, struct sample *smps[], unsigned *cnt)
|
|||
sum += smp->data[k].f;
|
||||
break;
|
||||
|
||||
case SIGNAL_TYPE_AUTO:
|
||||
case SIGNAL_TYPE_INVALID:
|
||||
case SIGNAL_TYPE_COMPLEX:
|
||||
case SIGNAL_TYPE_BOOLEAN:
|
||||
|
|
|
@ -56,7 +56,7 @@ static int cast_prepare(struct hook *h)
|
|||
|
||||
orig_sig = vlist_at_safe(&h->signals, c->signal_index);
|
||||
|
||||
type = c->new_type != SIGNAL_TYPE_AUTO ? c->new_type : orig_sig->type;
|
||||
type = c->new_type != SIGNAL_TYPE_INVALID ? c->new_type : orig_sig->type;
|
||||
name = c->new_name ? c->new_name : orig_sig->name;
|
||||
unit = c->new_unit ? c->new_unit : orig_sig->unit;
|
||||
|
||||
|
@ -125,7 +125,7 @@ static int cast_parse(struct hook *h, json_t *cfg)
|
|||
return -1;
|
||||
}
|
||||
else
|
||||
c->new_type = SIGNAL_TYPE_AUTO; // We use this constant to indicate that we dont want to change the type
|
||||
c->new_type = SIGNAL_TYPE_INVALID; // We use this constant to indicate that we dont want to change the type
|
||||
|
||||
if (new_name)
|
||||
c->new_name = strdup(new_name);
|
||||
|
|
|
@ -230,8 +230,7 @@ static int dp_prepare(struct hook *h)
|
|||
if (!orig_sig)
|
||||
return -1;
|
||||
|
||||
/** @todo: SIGNAL_TYPE_AUTO is bad here */
|
||||
if (orig_sig->type != SIGNAL_TYPE_COMPLEX && orig_sig->type != SIGNAL_TYPE_AUTO)
|
||||
if (orig_sig->type != SIGNAL_TYPE_COMPLEX)
|
||||
return -1;
|
||||
|
||||
ret = vlist_remove(&h->signals, d->signal_index + i);
|
||||
|
@ -255,8 +254,7 @@ static int dp_prepare(struct hook *h)
|
|||
if (!orig_sig)
|
||||
return -1;
|
||||
|
||||
/** @todo: SIGNAL_TYPE_AUTO is bad here */
|
||||
if (orig_sig->type != SIGNAL_TYPE_FLOAT && orig_sig->type != SIGNAL_TYPE_AUTO)
|
||||
if (orig_sig->type != SIGNAL_TYPE_FLOAT)
|
||||
return -1;
|
||||
|
||||
ret = vlist_remove(&h->signals, d->signal_index);
|
||||
|
|
15
lib/io.c
15
lib/io.c
|
@ -109,7 +109,7 @@ int io_init(struct io *io, const struct format_type *fmt, struct vlist *signals,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int io_init_auto(struct io *io, const struct format_type *fmt, int len, int flags)
|
||||
int io_init2(struct io *io, const struct format_type *fmt, enum signal_type type, int len, int flags)
|
||||
{
|
||||
int ret;
|
||||
struct vlist *signals;
|
||||
|
@ -121,7 +121,7 @@ int io_init_auto(struct io *io, const struct format_type *fmt, int len, int flag
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = signal_list_generate(signals, len, SIGNAL_TYPE_AUTO);
|
||||
ret = signal_list_generate(signals, len, type);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -159,17 +159,6 @@ int io_check(struct io *io)
|
|||
{
|
||||
assert(io->state != STATE_DESTROYED);
|
||||
|
||||
for (size_t i = 0; i < vlist_length(io->signals); i++) {
|
||||
struct signal *sig = (struct signal *) vlist_at(io->signals, i);
|
||||
|
||||
if (sig->type == SIGNAL_TYPE_AUTO) {
|
||||
if (io_type(io)->flags & IO_AUTO_DETECT_FORMAT)
|
||||
continue;
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
io->state = STATE_CHECKED;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -897,7 +897,6 @@ int comedi_write(struct node *n, struct sample *smps[], unsigned cnt, unsigned *
|
|||
break;
|
||||
|
||||
case SIGNAL_TYPE_INVALID:
|
||||
case SIGNAL_TYPE_AUTO:
|
||||
raw_value = 0;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
#define CONFIG_SV_DEFAULT_VLAN_ID 0
|
||||
|
||||
const struct iec61850_type_descriptor type_descriptors[] = {
|
||||
/* name, type, format, size, supported */
|
||||
/* name, iec_type, type, size, supported */
|
||||
{ "boolean", IEC61850_TYPE_BOOLEAN, SIGNAL_TYPE_BOOLEAN, 1, false, false },
|
||||
{ "int8", IEC61850_TYPE_INT8, SIGNAL_TYPE_INTEGER, 1, false, false },
|
||||
{ "int16", IEC61850_TYPE_INT16, SIGNAL_TYPE_INTEGER, 2, false, false },
|
||||
|
|
|
@ -91,15 +91,39 @@ static void iec61850_sv_listener(SVSubscriber subscriber, void *ctx, SVSubscribe
|
|||
if (!sig)
|
||||
continue;
|
||||
|
||||
switch (td->type) {
|
||||
case IEC61850_TYPE_INT8: smp->data[j].i = SVSubscriber_ASDU_getINT8(asdu, offset); break;
|
||||
case IEC61850_TYPE_INT16: smp->data[j].i = SVSubscriber_ASDU_getINT16(asdu, offset); break;
|
||||
case IEC61850_TYPE_INT32: smp->data[j].i = SVSubscriber_ASDU_getINT32(asdu, offset); break;
|
||||
case IEC61850_TYPE_INT8U: smp->data[j].i = SVSubscriber_ASDU_getINT8U(asdu, offset); break;
|
||||
case IEC61850_TYPE_INT16U: smp->data[j].i = SVSubscriber_ASDU_getINT16U(asdu, offset); break;
|
||||
case IEC61850_TYPE_INT32U: smp->data[j].i = SVSubscriber_ASDU_getINT32U(asdu, offset); break;
|
||||
case IEC61850_TYPE_FLOAT32: smp->data[j].f = SVSubscriber_ASDU_getFLOAT32(asdu, offset); break;
|
||||
case IEC61850_TYPE_FLOAT64: smp->data[j].f = SVSubscriber_ASDU_getFLOAT64(asdu, offset); break;
|
||||
switch (td->iec_type) {
|
||||
case IEC61850_TYPE_INT8:
|
||||
smp->data[j].i = SVSubscriber_ASDU_getINT8(asdu, offset);
|
||||
break;
|
||||
|
||||
case IEC61850_TYPE_INT16:
|
||||
smp->data[j].i = SVSubscriber_ASDU_getINT16(asdu, offset);
|
||||
break;
|
||||
|
||||
case IEC61850_TYPE_INT32:
|
||||
smp->data[j].i = SVSubscriber_ASDU_getINT32(asdu, offset);
|
||||
break;
|
||||
|
||||
case IEC61850_TYPE_INT8U:
|
||||
smp->data[j].i = SVSubscriber_ASDU_getINT8U(asdu, offset);
|
||||
break;
|
||||
|
||||
case IEC61850_TYPE_INT16U:
|
||||
smp->data[j].i = SVSubscriber_ASDU_getINT16U(asdu, offset);
|
||||
break;
|
||||
|
||||
case IEC61850_TYPE_INT32U:
|
||||
smp->data[j].i = SVSubscriber_ASDU_getINT32U(asdu, offset);
|
||||
break;
|
||||
|
||||
case IEC61850_TYPE_FLOAT32:
|
||||
smp->data[j].f = SVSubscriber_ASDU_getFLOAT32(asdu, offset);
|
||||
break;
|
||||
|
||||
case IEC61850_TYPE_FLOAT64:
|
||||
smp->data[j].f = SVSubscriber_ASDU_getFLOAT64(asdu, offset);
|
||||
break;
|
||||
|
||||
default: { }
|
||||
}
|
||||
|
||||
|
@ -253,13 +277,25 @@ int iec61850_sv_start(struct node *n)
|
|||
i->out.asdu = SVPublisher_addASDU(i->out.publisher, i->out.svid, node_name_short(n), i->out.confrev);
|
||||
|
||||
for (unsigned k = 0; k < vlist_length(&i->out.signals); k++) {
|
||||
struct iec61850_type_descriptor *m = (struct iec61850_type_descriptor *) vlist_at(&i->out.signals, k);
|
||||
struct iec61850_type_descriptor *td = (struct iec61850_type_descriptor *) vlist_at(&i->out.signals, k);
|
||||
|
||||
switch (td->iec_type) {
|
||||
case IEC61850_TYPE_INT8:
|
||||
SVPublisher_ASDU_addINT8(i->out.asdu);
|
||||
break;
|
||||
|
||||
case IEC61850_TYPE_INT32:
|
||||
SVPublisher_ASDU_addINT32(i->out.asdu);
|
||||
break;
|
||||
|
||||
case IEC61850_TYPE_FLOAT32:
|
||||
SVPublisher_ASDU_addFLOAT(i->out.asdu);
|
||||
break;
|
||||
|
||||
case IEC61850_TYPE_FLOAT64:
|
||||
SVPublisher_ASDU_addFLOAT64(i->out.asdu);
|
||||
break;
|
||||
|
||||
switch (m->type) {
|
||||
case IEC61850_TYPE_INT8: SVPublisher_ASDU_addINT8(i->out.asdu); break;
|
||||
case IEC61850_TYPE_INT32: SVPublisher_ASDU_addINT32(i->out.asdu); break;
|
||||
case IEC61850_TYPE_FLOAT32: SVPublisher_ASDU_addFLOAT(i->out.asdu); break;
|
||||
case IEC61850_TYPE_FLOAT64: SVPublisher_ASDU_addFLOAT64(i->out.asdu); break;
|
||||
default: { }
|
||||
}
|
||||
}
|
||||
|
@ -299,12 +335,12 @@ int iec61850_sv_start(struct node *n)
|
|||
return ret;
|
||||
|
||||
for (unsigned k = 0; k < vlist_length(&i->in.signals); k++) {
|
||||
struct iec61850_type_descriptor *m = (struct iec61850_type_descriptor *) vlist_at(&i->in.signals, k);
|
||||
struct iec61850_type_descriptor *td = (struct iec61850_type_descriptor *) vlist_at(&i->in.signals, k);
|
||||
struct signal *sig = (struct signal *) vlist_at(&n->in.signals, k);
|
||||
|
||||
if (sig->type == SIGNAL_TYPE_AUTO)
|
||||
sig->type = m->format;
|
||||
else if (sig->type != m->format)
|
||||
if (sig->type == SIGNAL_TYPE_INVALID)
|
||||
sig->type = td->type;
|
||||
else if (sig->type != td->type)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -372,12 +408,12 @@ int iec61850_sv_write(struct node *n, struct sample *smps[], unsigned cnt, unsig
|
|||
for (unsigned j = 0; j < cnt; j++) {
|
||||
unsigned offset = 0;
|
||||
for (unsigned k = 0; k < MIN(smps[j]->length, vlist_length(&i->out.signals)); k++) {
|
||||
struct iec61850_type_descriptor *m = (struct iec61850_type_descriptor *) vlist_at(&i->out.signals, k);
|
||||
struct iec61850_type_descriptor *td = (struct iec61850_type_descriptor *) vlist_at(&i->out.signals, k);
|
||||
|
||||
int ival = 0;
|
||||
double fval = 0;
|
||||
|
||||
switch (m->type) {
|
||||
switch (td->iec_type) {
|
||||
case IEC61850_TYPE_INT8:
|
||||
case IEC61850_TYPE_INT32:
|
||||
ival = sample_format(smps[j], k) == SIGNAL_TYPE_FLOAT ? smps[j]->data[k].f : smps[j]->data[k].i;
|
||||
|
@ -391,15 +427,27 @@ int iec61850_sv_write(struct node *n, struct sample *smps[], unsigned cnt, unsig
|
|||
default: { }
|
||||
}
|
||||
|
||||
switch (m->type) {
|
||||
case IEC61850_TYPE_INT8: SVPublisher_ASDU_setINT8(i->out.asdu, offset, ival); break;
|
||||
case IEC61850_TYPE_INT32: SVPublisher_ASDU_setINT32(i->out.asdu, offset, ival); break;
|
||||
case IEC61850_TYPE_FLOAT32: SVPublisher_ASDU_setFLOAT(i->out.asdu, offset, fval); break;
|
||||
case IEC61850_TYPE_FLOAT64: SVPublisher_ASDU_setFLOAT64(i->out.asdu, offset, fval); break;
|
||||
switch (td->iec_type) {
|
||||
case IEC61850_TYPE_INT8:
|
||||
SVPublisher_ASDU_setINT8(i->out.asdu, offset, ival);
|
||||
break;
|
||||
|
||||
case IEC61850_TYPE_INT32:
|
||||
SVPublisher_ASDU_setINT32(i->out.asdu, offset, ival);
|
||||
break;
|
||||
|
||||
case IEC61850_TYPE_FLOAT32:
|
||||
SVPublisher_ASDU_setFLOAT(i->out.asdu, offset, fval);
|
||||
break;
|
||||
|
||||
case IEC61850_TYPE_FLOAT64:
|
||||
SVPublisher_ASDU_setFLOAT64(i->out.asdu, offset, fval);
|
||||
break;
|
||||
|
||||
default: { }
|
||||
}
|
||||
|
||||
offset += m->size;
|
||||
offset += td->size;
|
||||
}
|
||||
|
||||
SVPublisher_ASDU_setSmpCnt(i->out.asdu, smps[j]->sequence);
|
||||
|
|
|
@ -135,7 +135,11 @@ int influxdb_write(struct node *n, struct sample *smps[], unsigned cnt, unsigned
|
|||
struct signal *sig = (struct signal *) vlist_at(smp->signals, j);
|
||||
union signal_data *data = &smp->data[k];
|
||||
|
||||
if (sig->type == SIGNAL_TYPE_AUTO || sig->type == SIGNAL_TYPE_COMPLEX) {
|
||||
if (
|
||||
sig->type != SIGNAL_TYPE_BOOLEAN &&
|
||||
sig->type != SIGNAL_TYPE_INTEGER &&
|
||||
sig->type != SIGNAL_TYPE_INTEGER
|
||||
) {
|
||||
warning("Unsupported signal format for node %s. Skipping", node_name(n));
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -206,9 +206,7 @@ int stats_node_parse(struct node *n, json_t *cfg)
|
|||
if (!sig->unit)
|
||||
sig->unit = strdup(stats_metrics[stats_sig->metric].unit);
|
||||
|
||||
if (sig->type == SIGNAL_TYPE_AUTO)
|
||||
sig->type = stats_types[stats_sig->type].signal_type;
|
||||
else if (sig->type != stats_types[stats_sig->type].signal_type)
|
||||
if (sig->type != stats_types[stats_sig->type].signal_type)
|
||||
error("Invalid type for signal %zu in node %s", i, node_name(n));
|
||||
|
||||
vlist_push(&s->signals, stats_sig);
|
||||
|
|
|
@ -282,7 +282,7 @@ enum signal_type sample_format(const struct sample *s, unsigned idx)
|
|||
|
||||
sig = (struct signal *) vlist_at_safe(s->signals, idx);
|
||||
|
||||
return sig ? sig->type : SIGNAL_TYPE_AUTO;
|
||||
return sig ? sig->type : SIGNAL_TYPE_INVALID;
|
||||
}
|
||||
|
||||
void sample_dump(struct sample *s)
|
||||
|
|
10
lib/signal.c
10
lib/signal.c
|
@ -34,7 +34,7 @@ int signal_init(struct signal *s)
|
|||
|
||||
s->name = NULL;
|
||||
s->unit = NULL;
|
||||
s->type = SIGNAL_TYPE_AUTO;
|
||||
s->type = SIGNAL_TYPE_INVALID;
|
||||
|
||||
s->refcnt = ATOMIC_VAR_INIT(1);
|
||||
|
||||
|
@ -335,8 +335,6 @@ enum signal_type signal_type_from_str(const char *str)
|
|||
return SIGNAL_TYPE_FLOAT;
|
||||
else if (!strcmp(str, "integer"))
|
||||
return SIGNAL_TYPE_INTEGER;
|
||||
else if (!strcmp(str, "auto"))
|
||||
return SIGNAL_TYPE_AUTO;
|
||||
else
|
||||
return SIGNAL_TYPE_INVALID;
|
||||
}
|
||||
|
@ -356,9 +354,6 @@ const char * signal_type_to_str(enum signal_type fmt)
|
|||
case SIGNAL_TYPE_INTEGER:
|
||||
return "integer";
|
||||
|
||||
case SIGNAL_TYPE_AUTO:
|
||||
return "auto";
|
||||
|
||||
case SIGNAL_TYPE_INVALID:
|
||||
return "invalid";
|
||||
}
|
||||
|
@ -410,7 +405,6 @@ void signal_data_set(union signal_data *data, const struct signal *sig, double v
|
|||
break;
|
||||
|
||||
case SIGNAL_TYPE_INVALID:
|
||||
case SIGNAL_TYPE_AUTO:
|
||||
memset(data, 0, sizeof(union signal_data));
|
||||
break;
|
||||
}
|
||||
|
@ -551,7 +545,6 @@ int signal_data_parse_str(union signal_data *data, const struct signal *sig, con
|
|||
break;
|
||||
}
|
||||
|
||||
case SIGNAL_TYPE_AUTO:
|
||||
case SIGNAL_TYPE_INVALID:
|
||||
return -1;
|
||||
}
|
||||
|
@ -591,7 +584,6 @@ int signal_data_parse_json(union signal_data *data, const struct signal *sig, js
|
|||
}
|
||||
|
||||
case SIGNAL_TYPE_INVALID:
|
||||
case SIGNAL_TYPE_AUTO:
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ int main(int argc, char *argv[])
|
|||
if (!fmt)
|
||||
throw RuntimeError("Invalid format: {}", dirs[i].name);
|
||||
|
||||
ret = io_init_auto(dirs[i].io, fmt, DEFAULT_SAMPLE_LENGTH, SAMPLE_HAS_ALL);
|
||||
ret = io_init2(dirs[i].io, fmt, SIGNAL_TYPE_FLOAT, DEFAULT_SAMPLE_LENGTH, SAMPLE_HAS_ALL);
|
||||
if (ret)
|
||||
throw RuntimeError("Failed to initialize IO: {}", dirs[i].name);
|
||||
|
||||
|
|
|
@ -169,7 +169,7 @@ check: if (optarg == endptr)
|
|||
if (!ft)
|
||||
throw RuntimeError("Unknown IO format '{}'", format);
|
||||
|
||||
ret = io_init_auto(&io, ft, DEFAULT_SAMPLE_LENGTH, SAMPLE_HAS_ALL);
|
||||
ret = io_init2(&io, ft, SIGNAL_TYPE_FLOAT, DEFAULT_SAMPLE_LENGTH, SAMPLE_HAS_ALL);
|
||||
if (ret)
|
||||
throw RuntimeError("Failed to initialize IO");
|
||||
|
||||
|
|
|
@ -355,7 +355,7 @@ check: if (optarg == endptr)
|
|||
if (!fmt)
|
||||
throw RuntimeError("Invalid format: {}", format);
|
||||
|
||||
ret = io_init_auto(&io, fmt, DEFAULT_SAMPLE_LENGTH, SAMPLE_HAS_ALL);
|
||||
ret = io_init2(&io, fmt, SIGNAL_TYPE_FLOAT, DEFAULT_SAMPLE_LENGTH, SAMPLE_HAS_ALL);
|
||||
if (ret)
|
||||
throw RuntimeError("Failed to initialize IO");
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ public:
|
|||
int ret;
|
||||
|
||||
io.state = STATE_DESTROYED;
|
||||
ret = io_init_auto(&io, format, DEFAULT_SAMPLE_LENGTH, 0);
|
||||
ret = io_init2(&io, format, SIGNAL_TYPE_FLOAT, DEFAULT_SAMPLE_LENGTH, 0);
|
||||
if (ret)
|
||||
throw RuntimeError("Failed to initialize IO");
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ Test(mapping, parse_nodes)
|
|||
for (unsigned j = 0; j < ARRAY_LEN(signal_names[i]); j++) {
|
||||
struct signal *sig;
|
||||
|
||||
sig = signal_create(signal_names[i][j], nullptr, SIGNAL_TYPE_AUTO);
|
||||
sig = signal_create(signal_names[i][j], nullptr, SIGNAL_TYPE_FLOAT);
|
||||
cr_assert_not_null(sig);
|
||||
|
||||
vlist_push(&n->in.signals, sig);
|
||||
|
|
Loading…
Add table
Reference in a new issue