mqtt_system_monitor/configuration.rs
1use serde::Deserialize;
2use serde_inline_default::serde_inline_default;
3use std::error::Error;
4
5/// Contains the configuration for communicating with the MQTT broker
6#[serde_inline_default]
7#[derive(Deserialize)]
8pub struct Mqtt {
9 /// Hostname or IP address. Default: localhost
10 #[serde_inline_default(String::from("localhost"))]
11 pub host: String,
12
13 /// Port of the connection to the broker. Default: 1883
14 #[serde_inline_default(1883)]
15 pub port: u16,
16
17 /// Username for the connection to the broker. Default: empty
18 #[serde(default)]
19 pub user: String,
20
21 /// Password for the connection to the broker. Default: empty
22 #[serde(default)]
23 pub password: String,
24
25 /// Prefix for the registration topic sent to Home Assistant. Default: homeassistant
26 ///
27 /// This must match the configuration of the MQTT integration in Home Assistant
28 ///
29 /// See <https://www.home-assistant.io/integrations/mqtt#discovery-options>
30 #[serde_inline_default(String::from("homeassistant"))]
31 #[serde(rename = "registration-prefix")]
32 pub registration_prefix: String,
33
34 /// Delay between each sensor report in seconds. Default: 10 seconds
35 #[serde_inline_default(10)]
36 pub update_period: u64,
37
38 /// Name of the device entity. It should be unique in Home Assistant. Default: machine hostname
39 #[serde(default = "hostname")]
40 pub entity: String,
41}
42
43/// Contains the configuration for the sensors
44#[derive(Deserialize)]
45pub struct Sensors {
46 /// If set, contains a temperature label to search in `sysinfo`'s component reports.
47 pub temperature: Option<String>,
48
49 /// If set, contains a list of network interface to monitor.
50 #[serde(default)]
51 pub network: Vec<String>,
52}
53
54/// Contains all the configuration for `mqtt-system-monitor`
55#[serde_inline_default]
56#[derive(Deserialize)]
57pub struct Configuration {
58 /// Contains the configuration for communicating with the MQTT broker
59 pub mqtt: Mqtt,
60
61 /// Contains the configuration for the sensors
62 pub sensors: Sensors,
63
64 /// Sets the verbosity of the logs.
65 /// * 1 => Error
66 /// * 2 => Warning
67 /// * 3 => Info
68 /// * 4 => Debug
69 /// * 5 => Trace
70 #[serde_inline_default(2)]
71 #[serde(rename = "log-verbosity")]
72 pub log_verbosity: usize,
73}
74
75fn hostname() -> String {
76 sysinfo::System::host_name().expect("Cannot read hostname")
77}
78
79impl Configuration {
80 /// Load the configuration from a file
81 ///
82 /// ## Example
83 ///
84 /// ```
85 /// use mqtt_system_monitor::{configuration, Configuration};
86 ///
87 /// let config = Configuration::load("conf/mqtt-system-monitor.conf").expect("Cannot load configuration");
88 ///
89 /// assert_eq!(config.mqtt.host, "localhost");
90 /// ```
91 pub fn load(path: &str) -> Result<Configuration, Box<dyn Error>> {
92 toml::from_str(std::fs::read_to_string(path)?.as_str()).map_err(|err| err.into())
93 }
94}
95
96#[cfg(test)]
97mod tests {
98 use super::*;
99
100 /// Test that we can properly load the default configuration
101 #[test]
102 fn test_default_config() -> Result<(), Box<dyn Error>> {
103 let conf = Configuration::load("conf/mqtt-system-monitor.conf")?;
104
105 assert_eq!(conf.mqtt.host, String::from("localhost"));
106 assert_eq!(conf.mqtt.registration_prefix, String::from("homeassistant"));
107
108 // By default, the entity name will be the hostname of the machine
109 assert_eq!(conf.mqtt.entity, hostname());
110
111 // Sensors are off by default
112 assert_eq!(conf.sensors.temperature, None);
113 assert!(conf.sensors.network.is_empty());
114
115 Ok(())
116 }
117}