Teleinfo: su contador Linky en Gladys con el módulo LiXee TIC

¡Hola a todos! Os presento Teleinfo, una integración externa que lee la teleinformación (TIC) de vuestro contador Linky o electrónico con el módulo LiXee TIC sobre rail DIN (USB, unos 30 €). Código fuente: github.com/prohand/gladys-teleinfo.

El punto importante: el USB

Una integración externa de Gladys no puede leer una clave USB serie. Es lo primero que hay que saber antes de comprar el módulo.

  • Las integraciones externas funcionan cada una en su propio contenedor Docker, aislado por Gladys (sistema de archivos de solo lectura, sin acceso al hardware).
  • El manifiesto de una integración puede solicitar acceso al hardware, pero solo entre 4 clases: coral-usb, coral-pcie, gpu y video. No existe ninguna clase para un puerto serie (/dev/ttyUSB0, /dev/ttyACM0…).
  • Estas clases solo se conceden a los subcontenedores, y nunca en forma de ruta /dev libre.

Consecuencia: conectar el módulo LiXee al servidor Gladys no es suficiente. La integración no lo verá, aunque esté correctamente detectado por Linux.

El ZLinky (la versión Zigbee del LiXee) no tiene este problema: pasa por Zigbee2MQTT. Pero la versión USB sobre rail DIN, más barata, necesita un relé de red.

La solución: ser2net

ser2net comparte el puerto serie del módulo en la red (TCP bruto), y la integración se conecta a él:

Contador (I1/I2) -> módulo LiXee (USB) -> ser2net (TCP 2000) -> integración Teleinfo -> Gladys

ser2net funciona en la máquina donde está conectado el módulo: el servidor Gladys mismo, o una Raspberry Pi cerca del cuadro eléctrico (práctico, el cable USB está limitado a unos 5 m).

sudo apt install ser2net
ls -l /dev/serial/by-id/

Luego /etc/ser2net.yaml:

connection: &teleinfo
  accepter: tcp,2000
  enable: on
  options:
    kickolduser: true
  connector: serialdev,/dev/serial/by-id/usb-XXXX-if00-port0,1200e71,local
  • 1200e71 para el modo histórico (contadores electrónicos, y la mayoría de los Linky por defecto).
  • 9600e71 para un Linky en modo estándar.
  • Luego sudo systemctl restart ser2net && sudo systemctl enable ser2net.

Atención: ser2net no tiene contraseña. Mantén este puerto en tu red local, nunca abierto a Internet.

Lo que se sube a Gladys

El modo (histórico o estándar) se detecta automáticamente. Se crea un dispositivo por contador, con solo los valores que tu contador envía (monofásico o trifásico, Base, HC/HP, Tempo, EJP).

  • Modo histórico: índice (Base, HC/HP, EJP, Tempo) en kWh, potencia aparente (PAPP), intensidad instantánea y máxima, intensidad suscrita, período tarifario, excedencia (ADPS).
  • Modo estándar: energía total consumida y por índice, energía inyectada, potencia aparente instantánea y máxima, corriente y tensión efectivas, tensión media, curva de carga, tarifa en curso.

Las categorías y unidades son las mismas que las utilizadas por Gladys para el ZLinky en Zigbee: un contador se muestra igual en ambos casos.

Los valores se envían cada 60 s por defecto (ajustable de 15 s a 1 h), solo cuando cambian, para no llenar el historial.

Escenas y tablero de control (Gladys 5.1+)

La integración añade sus propias tarjetas en el editor de escenas (categoría Integraciones) y un widget para el tablero de control.

  • Disparador «Cambio de período tarifario»: lanza la escena al pasar de HC ↔ HP. Filtro posible sobre el nuevo período (horas valle, punta, base). Ejemplo: calentador de agua en horas valle.
  • Disparador «Excedencia de potencia suscrita»: advierte antes de que se dispare el interruptor. Un solo disparo por excedencia, aunque la potencia oscile alrededor del límite.
  • Acción «Leer el contador»: devuelve potencia, período, índice total y excedencia, para una condición o un mensaje.
  • Widget «Contador eléctrico»: potencia en directo, índice, curva de 24 h, período tarifario, excedencia y estado de la recepción.

Estas funciones requieren Gladys 5.1 o más reciente.

Instalación

  1. Conecta el módulo LiXee a las bornas I1 e I2 del contador (sin polaridad, corriente cortada en el cuadro).
  2. Instala y configura ser2net como se indica arriba.
  3. En Gladys, instala la integración Teleinfo, luego introduce la dirección IP de la máquina ser2net y el puerto (2000).
  4. Haz clic en Probar la conexión: el número del contador y la potencia actual se muestran. Añade luego el contador desde la pestaña Descubrimiento.

El estado de conexión en la pantalla de Configuración indica claramente el problema: pasarela inalcanzable, o conectado pero sin tramas válidas (velocidad incorrecta o cableado). La guía detallada está en la documentación.

Lo que busco

  • Probadores con un contador real: la integración se ha probado con tramas simuladas, pero aún no en un Linky real. @mutmut, habías ofrecido probar con tu módulo LiXee TIC rail DIN aquí: ¡con mucho gusto! Si tu teleinfo2mqtt ya lee el puerto, tendrás que detenerlo durante la prueba (solo un programa a la vez en el puerto serie). También son bienvenidos los comentarios en trifásico y en modo estándar.
  • Una opinión sobre el acceso serie: @pierre-gilles, una clase de hardware serial (para /dev/ttyUSB* / /dev/ttyACM*), concedida por el usuario como coral-usb o video, evitaría ser2net. También serviría para otras integraciones en clave USB, como el RFPlayer que también se solicita en el hilo. ¿Es posible desde Gladys?

¡Gracias por vuestros comentarios!

¡Gracias @prohand!
Veo que no es tan simple en cuanto hay que conectar algo por USB por el momento, esperaba algo plug&play como lo tengo con teleinfo2mqtt :frowning:

¿Lo instalas en el host o en el docker de Gladys o en el docker de la integración externa?

¿Esto significa que cuando pase de histórico a estándar, hay que modificar el yaml y reiniciar el servicio?

¿Cómo se detecta automáticamente? ¿por el código de arriba?
¿No es posible leer los tramas, analizar el contenido y deducir si es histórico o estándar?
Las variables dentro son bastante distintas para uno y otro, pensé que sería más simple que eso :frowning:

Muy bien, porque teleinfo2mqtt devuelve toda la información en cada consulta (10s actualmente porque hay demasiados datos), incluso si algunas no cambian (por ejemplo, el día Tempo rojo).
Por otro lado, para el PAPP (potencia instantánea en histórico, no conozco el equivalente en estándar), ¿es posible ajustarlo más bajo (por ejemplo, 1s)?
Lo uso para ver si hay algún exceso (y gestionar la desconexión) y en 15s se puede tener el Linky que « dispara » si se extrae demasiada potencia en el instante T (carga de coche + agua caliente + calefacción, por ejemplo).

Último punto, tengo dispositivos virtuales MQTT para gestionar mis índices Tempo, ¿cómo debería proceder para migrar (histórico, conso30, cout30, etc.) a esta integración?

¡Gracias @mutmut por estas buenas preguntas! Las responderé punto por punto.

1. ¿Dónde instalar ser2net?

  • Directamente en la máquina (el host) donde el módulo LiXee está conectado por USB, con sudo apt install ser2net.
  • Ni en el Docker de Gladys, ni en el de la integración: ninguno de los dos ve el puerto USB.
  • Para información, teleinfo2mqtt es «plug & play» porque le das el puerto con --device en su propio docker run. Una integración externa no puede hacer eso: es Gladys quien crea su contenedor, y sin acceso al puerto serie.

2. ¿Cambiar de histórico a estándar: modificar el yaml?

  • Sí: reemplazas 1200e71 por 9600e71, luego sudo systemctl restart ser2net.
  • Esto normalmente solo ocurre una vez en la vida del contador, cuando solicitas el cambio a modo estándar.
  • Si lo olvidas, la integración te lo dice en su estado: «Conectado, pero ningún marco TIC válido: verifique la velocidad de ser2net (1200 o 9600 baudios)».

3. ¿Cómo se detecta el modo?

  • Exactamente como lo describes: la integración lee los marcos. En histórico, los campos están separados por un espacio, en estándar por una tabulación. Los nombres de los campos (PAPP, SINSTS…) también cambian.
  • Pero la velocidad se juega un nivel más abajo. A la velocidad incorrecta, solo se reciben octetos ilegibles, por lo que no hay marcos para analizar. Y es ser2net quien abre el puerto serie, con la velocidad de su archivo de configuración, no la integración.
  • Una pista a explorar: ser2net maneja el protocolo RFC 2217, que permite al cliente cambiar la velocidad de forma remota. La integración podría entonces intentar 1200 y luego 9600 por sí misma.

4. ¿PAPP más a menudo que cada 15 s?

  • Los valores publicados en Gladys no bajan de 15 s. Gladys limita una integración a 300 valores por minuto, y cada valor se convierte en una línea de historial. Un contador trifásico en modo estándar superaría rápidamente este límite.
  • Pero para el desconexión, no se necesita el historial. El disparador «Excedencia de potencia suscrita» analiza cada marco, por lo que cada 1 a 2 s, independientemente del intervalo de publicación:
    • en histórico, se basa en ADPS, que el contador envía tan pronto como se excede la intensidad suscrita;
    • en estándar (el equivalente de PAPP es SINSTS), compara SINSTS con la potencia suscrita (PREF).
  • Se activa una sola vez por excedencia. La excedencia se considera terminada después de 60 s sin nueva señal.
  • La acción «Leer el contador» también devuelve el último marco recibido (de 1 a 2 s de edad), y no el último valor publicado. Por lo tanto, puedes usarlo en una condición de escena.

5. Migrar tus dispositivos MQTT (índice Tempo, histórico, conso30, cout30)

  • conso30 / cout30: nada que recrear. Gladys los calcula solo a partir de los índices enviados por la integración, como para el ZLinky. Los precios Tempo se ajustan en el contrato de energía de Gladys.
  • Histórico: la integración no puede importar valores antiguos, solo publica los valores actuales.
  • Gladys tiene una función «Migrar» que mueve el historial, las escenas y los tableros de un dispositivo a otro. Hoy, el botón solo existe en las integraciones obsoletas (Netatmo, Tuya, Hue…), no en MQTT. @pierre-gilles, ¿podríamos abrirlo a los dispositivos MQTT?
  • Atención a las unidades: la integración publica los índices en kWh. Si tus índices MQTT están en Wh, una migración movería los valores sin convertirlos.
  • Mientras tanto: mantén tus antiguos dispositivos MQTT para su historial, y deja que ambos funcionen en paralelo.