Architecture
The project started as a way to learn Rust and became something that powered my house. After a while some companies asked to get their cloud services or meters integrated.
The software itself uses tokio, an async layer for Rust to handle concurrent workloads. Each protocol contains a Manager for that part of the configuration. Some protocols spawn threads even if they are not configured because they just listen on MQTT topics (like wireless M-Bus).
Each Manager implements a start_thread function which is the entry point of the protocol. That function should never return; if it does, energy2mqtt exits and the init daemon or container service will restart it.
A YAML based configuration is used to specify the protocol instances. That is user editable as well as updatable using the built-in REST API. See the API documentation about how to use it.
A state storage system is able to keep the current values of a sensor in order to fetch them again. That can be helpful if you want to build differences based on those values or need some data to build a complete meter record. The latter part is often needed by protocols using low power wireless transmission. Those sensors send some values in the first telegram and the rest on the next one, or update only values that have changed but not everything. Have a look at src/metering_zennerdatahub/handle_lora.rs to see how that works.