113 lines
4.2 KiB
C
113 lines
4.2 KiB
C
#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 }}" },
|
|
{ "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);
|
|
}
|
|
|