tic2mqtt-c/homeassistant.c

113 lines
4.2 KiB
C
Raw Normal View History

2021-08-04 12:24:08 +02:00
#include "homeassistant.h"
#include "mqtt.h"
#include "logger.h"
#include <json-c/json.h>
#include <stddef.h>
#include <stdio.h>
typedef struct {
const char *tag; // TIC Tag
const char *state_class; // HA State Class
const char *device_class; // HA Device Class
const char *name; // HA name
const char *unit; // HA unit
const bool last_reset; // HA LastReset present
const char *value_template; // HA Template for value
} ha_config_desc;
static ha_config_desc ha_config_descs[] = {
{ "PAPP", "measurement", "power", "Puissance Apparente", "VA", },
{ "IINST", "measurement", "current", "Intensité Instantanée", "A", },
{ "HCHP", "total_increasing", "energy", "Energie Heures Pleines", "kWh", false, "{{ (value | float) / 1000 }}" },
{ "HCHC", "total_increasing", "energy", "Energie Heures Creuses", "kWh", false, "{{ (value | float) / 1000 }}" },
2021-08-04 12:24:08 +02:00
{ "PTEC", NULL, NULL, "Période Tarifaire en cours", NULL, false,
"{% if value == \"TH..\" %}Toutes les Heures"
"{% elif value == \"HC..\" %}Heures Creuses"
"{% elif value == \"HP..\" %}Heures Pleines"
"{% elif value == \"HN..\" %}Heures Normales"
"{% elif value == \"PM..\" %}Heures de Pointe Mobile"
"{% else %}{{value}}"
"{% endif %}" },
{ NULL }
};
/* workaround for libjson-c 0.12 which always escape
* strings while serializing
*/
static void unescape_str(const char *str)
{
const char *s;
char *d;
for (s = str, d = (char*)str; *s; s++, d++) {
if (*s == '\\' && *(s+1) == '/')
s++;
*d = *s;
}
*d = '\0';
}
void ha_config_init(const char *tic_name, struct mosquitto *mosq_tic)
{
ha_config_desc *desc;
// char payload[512];
json_object *device = json_object_new_object();
json_object *dev_ids = json_object_new_array();
json_object_array_add(dev_ids, json_object_new_string(tic_name));
json_object_object_add(device, "identifiers", dev_ids);
json_object_object_add(device, "manufacturer", json_object_new_string("Enedis"));
json_object_object_add(device, "model", json_object_new_string("Linky Monophasé"));
json_object_object_add(device, "name", json_object_new_string(tic_name));
json_object_object_add(device, "sw_version", json_object_new_string("0.0.1"));
for (desc = &ha_config_descs[0]; desc->tag != NULL; desc++) {
char topic[TOPIC_MAXLEN+1];
char vtopic[TOPIC_MAXLEN+1];
char uid[TOPIC_MAXLEN+1];
char name[TOPIC_MAXLEN+1];
snprintf(topic, TOPIC_MAXLEN, "homeassistant/sensor/%s/%s/config", tic_name, desc->tag);
snprintf(vtopic, TOPIC_MAXLEN, "tic2mqtt/%s/%s", tic_name, desc->tag);
snprintf(name, TOPIC_MAXLEN, "%s %s", tic_name, desc->name);
snprintf(uid, TOPIC_MAXLEN, "tic2mqtt_%s_%s", tic_name, desc->tag);
json_object *obj = json_object_new_object();
json_object_object_add(obj, "device", json_object_get(device));
json_object_object_add(obj, "name", json_object_new_string(name));
json_object_object_add(obj, "unique_id", json_object_new_string(uid));
json_object_object_add(obj, "state_topic", json_object_new_string(vtopic));
if (desc->state_class)
json_object_object_add(obj, "state_class", json_object_new_string(desc->state_class));
if (desc->device_class)
json_object_object_add(obj, "device_class", json_object_new_string(desc->device_class));
if (desc->unit)
json_object_object_add(obj, "unit_of_measurement", json_object_new_string(desc->unit));
if (desc->value_template)
json_object_object_add(obj, "value_template", json_object_new_string(desc->value_template));
if (desc->last_reset) {
json_object_object_add(obj, "last_reset_topic", json_object_new_string(vtopic));
json_object_object_add(obj, "last_reset_value_template", json_object_new_string("1970-01-01T00:00:00+00:00"));
}
const char *payload = json_object_to_json_string(obj);
unescape_str(payload);
log_info("%s\n%s\n", topic, payload);
if (mosq_tic) {
int res = mqtt_publish(mosq_tic, topic, NULL, payload, TIC_QOS);
if (res != 0)
log_error("Cannot publish topic %s: %s\n", topic, mqtt_strerror(res));
}
json_object_put(obj);
}
json_object_put(device);
}