From ae9fdcca4cbe82f00166912a9ab78dffdf5be492 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Sat, 1 Jun 2013 00:23:31 +0000 Subject: cethcan: beancounters support --- cethcan/beanctr.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 cethcan/beanctr.c (limited to 'cethcan/beanctr.c') diff --git a/cethcan/beanctr.c b/cethcan/beanctr.c new file mode 100644 index 0000000..d381c79 --- /dev/null +++ b/cethcan/beanctr.c @@ -0,0 +1,91 @@ +#include "cethcan.h" + +struct bean { + struct can_user *u; + + char *name; + unsigned logical_addr; + + uint8_t raw; + json_t *vals[2]; + + time_t change, valid; +}; + +static void bean_json_handler(void *arg, json_t *json, enum json_subtype type) +{ + struct bean *b = arg; + json_t *bobj = json_object(); + + json_object_set_new(bobj, "klass", json_string("beancounter")); + json_object_set_new(bobj, "addr", json_integer(b->logical_addr)); + + json_object_set_new(bobj, "raw", json_integer(b->raw)); + json_object_set_new(bobj, "value", json_boolean(b->raw & 1)); + json_object_set_new(bobj, "text", json_incref(b->vals[b->raw & 1])); + if (type != JSON_LONGPOLL) + json_object_set_new(bobj, "ts", json_integer(b->valid)); + json_object_set_new(bobj, "tschg", json_integer(b->change)); + + json_object_set_new(json, b->name, bobj); +} + +static void bean_can_handler(void *arg, struct can_message *msg) +{ + struct bean *b = arg; + unsigned laddr; + uint8_t dval; + + if ((msg->daddr & CANA_PROTOCOL) != CANA_SENSOR) + return; + + laddr = msg->daddr & 0xfff; + if (b->logical_addr < laddr) + return; + if (b->logical_addr - laddr >= msg->dlc) + return; + dval = msg->bytes[b->logical_addr - laddr]; + + time(&b->valid); + if (dval != b->raw || b->change == 0) { + b->raw = dval; + time(&b->change); + lprintf("%s: set %02x", b->u->name, dval); + + json_bump_longpoll(); + } +} + +int bean_init_conf(json_t *config) +{ + struct bean *b; + json_t *vals; + + if (!json_is_object(config)) { + lprintf("light config must be an object/dictionary"); + return 1; + } + if (!json_is_integer(json_object_get(config, "addr"))) { + lprintf("light config must have an 'addr' key"); + return 1; + } + if (!json_is_string(json_object_get(config, "name"))) { + lprintf("light config must have a 'name' key"); + return 1; + } + vals = json_object_get(config, "values"); + if (!json_is_array(vals) || json_array_size(vals) != 2) { + lprintf("light config must have a 'values' array of len 2"); + return 1; + } + + b = calloc(sizeof(*b), 1); + b->name = strdup(json_string_value(json_object_get(config, "name"))); + b->logical_addr = json_integer_value(json_object_get(config, "addr")); + b->vals[0] = json_array_get(vals, 0); + b->vals[1] = json_array_get(vals, 1); + + b->u = can_register_alloc(b, bean_can_handler, "bean[%s]", b->name); + b->u->json = bean_json_handler; + return 0; +} -- cgit v1.2.1