Convert TeleInfo frames from a Linky meter's serial port to Home Assistant-compatible MQTT messages.

Overview

teleinfo2mqtt-rs

Convert TeleInfo frames from a Linky meter's serial port to Home Assistant-compatible MQTT messages.

Overview

sequenceDiagram
    participant tic as Linky TIC
    participant pitinfo as PITInfo
    participant rpiz as Raspberry Pi Zero
    box green This project
    participant t2m as teleinfo2mqtt-rs
    end
    participant mqtt as MQTT Broker
    participant ha as Home Assistant
    tic->>pitinfo: IEC 62056-21 serial
    pitinfo->>rpiz: GPIO serial
    rpiz->>t2m: Linux serial port
    t2m->>mqtt: mqtt
    mqtt->>ha: mqtt integration

Reasoning

This is a rewrite of the fmartinou/teleinfo2mqtt that is written in Javascript.

This was only done for learning purposes, as the original project is working perfectly fine.

The only advantage of this project is that it is written in Rust, which means a single binary to deploy and very low resource usage, which is perfect for a low-power device like a Raspberry Pi Zero 2 W, which is what I use.

It uses less than 1% of CPU and 2-3 MB of RAM on my Raspberry Pi:

pi@raspberrypiz ~> ps -p $(pgrep teleinfo2mqtt-r) -o %cpu,%mem,rss
%CPU %MEM   RSS
 0.5  0.5  2560

Caveats

  • Only supports "historical" Linky mode, not "standard" mode, because my Linky is in historical mode.
  • MQTT discovery for Home Assistant is not implemented

Usage

The following environment variables are required:

  • MQTT_HOST: the MQTT broker to connect to, e.g. 192.168.1.42
  • MQTT_USERNAME: the MQTT broker username
  • MQTT_PASSWORD: the MQTT broker password

The following environment variables are optional:

  • SERIAL_PORT: the serial port to read from, defaults to /dev/ttyS0
  • MQTT_PORT: the MQTT broker port to connect to, defaults to 1883

The binary can then be run with:

./teleinfo2mqtt-rs

My setup

My setup is as follows:

  • Linky meter manufactured by Itron, historical mode
  • PiTInfo shield to get the serial data from the TIC module through the GPIO pins
  • Raspberry Pi Zero 2 W to run the binary
  • Mosquitto as the MQTT broker to receive the MQTT messages, running as an addon in Home Assistant
  • Home Assistant to integrate the MQTT messages

Setup

Home Assistant integration

Development

The usual Rust commands apply:

cargo build
cargo run

Architecture

The project is architected around Streams from futures.

---
title: Data flow
---
graph TD
    subgraph Main flow
        buffer[Serial buffer] -->|Reader| A
        A[SerialPort ASCII] -->|Stream| B[Teleinfo raw frame]
        B -->|Stream| C[TeleinfoFrame struct]
        C -->|Stream| task
        subgraph task[Tokio async task]
            D[MQTT publisher] -->|MQTT| E[MQTT broker]
        end
    end

    subgraph Tokio async task
    Z[MQTT even loop] -->Z
    end

Cross-compilation

Unfortunately, I couldn't get cross-compilation to work from macOS aarch64-apple-darwin to aarch64-unknown-linux-gnu because of the libudev-dev dependency on Linux.

A VS Code Dev Container is provided to have a working rust-analyzer and clippy in VSCode on macOS and to be able to compile the project on Linux.

TeleInfo specs

PDF from Enedis can be found under docs/Enedis-NOI-CPT_54E.pdf.

The important stuff is for historical mode is:

Physical layer

  • The baud rate is 1200 bauds
  • 7 data bits are used to represent each ASCII character

The teleinfo data can be read from the serial port using picocom:

sudo picocom -b 1200 -d 7 /dev/ttyS0

Data link layer

The TIC sends frames continuously. Each frame is separated by a delay of 16.7 ms < t < 33.4 ms.

  • Each frame is composed of multiple data sets
  • Each data set is composed of a label, a value and a checksum
  • Each frame starts with "Start TeXt" STX (0x02) and ends with "End TeXt" ETX (0x03)
STX<data set><data set>...<data set>ETX

A data set is composed of:

\n<Label>\t<Value>\t<Checksum>\r

The checksum is (S1 & 0x3F) + 0x20, considering S1 the sum of the ASCII values from the label (included) to the checksum (excluded)

A full frame on my Linky meter looks like this:

0x02
ADCO 012345678912 B
OPTARIF BASE 0
ISOUSC 30 9
BASE 002815235 %
PTEC TH.. $
IINST 001 X
IMAX 090 H
PAPP 00260 )
HHPHC A ,
MOTDETAT 000000 B0x03

Application layer

In the code, the frame is represented as:

pub struct TeleinfoFrame {
    pub adco: String,     // Adresse du compteur
    pub optarif: String,  // Option tarifaire
    pub isousc: String,   // Intensité souscrite, en A
    pub base: String,     // Index option base, en Wh
    pub ptec: String,     // Période tarifaire en cours
    pub iinst: String,    // Intensité instantanée, en A
    pub imax: String,     // Intensité maximale appelée, en A
    pub papp: String,     // Puissance apparente, en VA (arrondie à la dizaine la plus proche)
    pub hhphc: String,    // Horaire Heures Pleines Heures Creuses
    pub motdetat: String, // Mot d'état du compteur
}
You might also like...
A STOMP client in Rust. Compatible with RabbitMQ, ActiveMQ.

stomp-rs stomp-rs provides a full STOMP 1.2 client implementation for the Rust programming language. This allows programs written in Rust to interact

A decentralized, censorship-resistant, and incentive-compatible packet-routing overlay network

About Earendil is a decentralized, censorship-resistant packet-routing overlay network designed for performance and censorship resistance. It enables

A skyline mod that enables manual choosing of desired input latency in Smash Ultimate, compatible with every online mode.

Latency Slider (Definitive Edition) This is a fork of - and an improvement upon - the original "Arena Latency Slider". Unfortunately, upon SSBU updati

Convert your docker-compose into excalidraw
Convert your docker-compose into excalidraw

excalidocker-rs Rust-based utility to convert docker-compose.yaml files into excalidraw files. Key features Transform your local docker-compose files

A high performance TCP SYN port scanner.

Armada A High-Performance TCP SYN scanner What is Armada? Armada is a high performance TCP SYN scanner. This is equivalent to the type of scanning tha

Simple utility to ping a TCP port.

TcpPing Simple utility to ping a TCP port. Example tcpping 1.1.1.1 53 -b en0 -i 1 -t 4 Connected to 1.1.1.1:53 in 21 ms Connected to 1.1.1.1:53 in 3

A cross-platform, user-space WireGuard port-forwarder that requires no system network configurations.

Cross-platform, user-space WireGuard port-forwarder that requires no system network configurations.

A fast, stable, efficient, and lightweight intranet penetration, port forwarding tool supports multiple connections, cascading proxy, and transmission encryption
A fast, stable, efficient, and lightweight intranet penetration, port forwarding tool supports multiple connections, cascading proxy, and transmission encryption

A fast, stable, efficient, and lightweight intranet penetration, port forwarding tool supports multiple connections, cascading proxy, and transmission encryption

Rust port of stb_image_write.h

Overview stb_image_write_rust is Rust port of stb_image_write.h, which is library to save images in BMP, JPG, PNG and TGA formats. The porting was don

Owner
Stanislas
tired of computers
Stanislas
Converts Hikvision camera events to MQTT

HikSink streams Hikvision camera and NVR events (motion, line crossing, tamper, illegal logins, etc.) to MQTT messages for consumption by home automat

Corner Bit 48 Dec 27, 2022
TeleMQ is an experimental MQTT broker implemented in Rust language.

TeleMQ TeleMQ is an experimental MQTT broker implemented in Rust language. The broker implements MQTT version 3.1.1 specification. License This projec

null 12 Dec 27, 2022
MQTT over QUIC

MQuicTT ?? This is a pre-alpha project, tread carefully ?? A rustlang utility/library for MQTT over QUIC. QUIC allows us to send data over multiple co

null 29 Dec 16, 2022
Small MQTT router. Allows creating multiple inputs/outputs and run action when input triggers.

MQRT Small MQTT router. Allows creating multiple inputs/outputs and run action when input triggers. Features multi-(input/output) multiple actions tie

Nazar Gondaruk 0 Jan 4, 2022
Export statistics of Mosquitto MQTT broker (topic: $SYS) to Prometheus

Preface The Mosquitto MQTT broker provides a number of statistics on the special $SYS/# topic (see mosquitto(8)). Build requirements As a Rust program

Bobobo-bo Bo-bobo 2 Dec 15, 2022
Pure rust mqtt cilent

NOTE: Archived. No further development under this repo. Follow progress of a different implementation here Pure rust MQTT client which strives to be s

Ather Energy Pvt Ltd 201 Dec 2, 2022
This Intelligent Transportation Systems (ITS) MQTT client based on the JSon ETSI specification transcription provides a ready to connect project for the mobility

This Intelligent Transportation Systems (ITS) MQTT client based on the JSon ETSI specification transcription provides a ready to connect project for the mobility (connected and autonomous vehicles, road side units, vulnerable road users,...). Let's connect your device or application to our Intelligent Transport Systems (ITS) platform!

Orange 4 Nov 29, 2022
Subscribe to MQTT topics and push them to InfluxDB 1.x or v2

MQTT 2 InfluxDB Subscribe to MQTT topics and push them to InfluxDB 1.x or v2 Something like Telegraf for MQTT like it does with inputs.mqtt_consumer a

null 2 Feb 20, 2022
Resolved - a simple DNS server for home networks

resolved resolved (pronounced "resolved", not "resolved") is a simple DNS server for home networks. To that end, it supports: Recursive and non-recurs

Michael Walker 17 Sep 27, 2022
pam-send-slack-message is a program that publishes messages on slack when a linux server is accessed through ssh.

pam-send-slack-message pam-send-slack-message is a program that publishes messages on slack when the linux server is accessed through ssh. Installatio

Iuri Diniz 2 Aug 17, 2022