Major updates: - Complete Rust rewrite (pilot-v2/) with working MQTT client - Fixed MQTT event loop deadlock (background task pattern) - Battery telemetry for Linux (auto-detected via /sys/class/power_supply) - Home Assistant auto-discovery for all sensors and switches - Comprehensive documentation (AVANCEMENT.md, CLAUDE.md, roadmap) - Docker test environment with Mosquitto broker - Helper scripts for development and testing Features working: ✅ MQTT connectivity with LWT ✅ YAML configuration with validation ✅ Telemetry: CPU, memory, IP, battery (Linux) ✅ Commands: shutdown, reboot, sleep, screen (dry-run tested) ✅ HA discovery and integration ✅ Allowlist and cooldown protection Ready for testing on real hardware. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
84 lines
14 KiB
HTML
84 lines
14 KiB
HTML
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="A pure rust MQTT client which strives to be robust, efficient and easy to use. This library is backed by an async (tokio) eventloop which handles all the robustness and and efficiency parts of MQTT but naturally fits into both sync and async worlds as we’ll see"><title>rumqttc - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../static.files/rustdoc-ca0dd0c4.css"><meta name="rustdoc-vars" data-root-path="../" data-static-root-path="../static.files/" data-current-crate="rumqttc" data-themes="" data-resource-suffix="" data-rustdoc-version="1.92.0 (ded5c06cf 2025-12-08)" data-channel="1.92.0" data-search-js="search-d69d8955.js" data-stringdex-js="stringdex-c3e638e9.js" data-settings-js="settings-c38705f0.js" ><script src="../static.files/storage-e2aeef58.js"></script><script defer src="../crates.js"></script><script defer src="../static.files/main-ce535bd0.js"></script><noscript><link rel="stylesheet" href="../static.files/noscript-263c88ec.css"></noscript><link rel="alternate icon" type="image/png" href="../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../static.files/favicon-044be391.svg"></head><body class="rustdoc mod crate"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><rustdoc-topbar><h2><a href="#">Crate rumqttc</a></h2></rustdoc-topbar><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../rumqttc/index.html">rumqttc</a><span class="version">0.24.0</span></h2></div><div class="sidebar-elems"><ul class="block"><li><a id="all-types" href="all.html">All Items</a></li></ul><section id="rustdoc-toc"><h3><a href="#">Sections</a></h3><ul class="block top-toc"><li><a href="#a-simple-synchronous-publish-and-subscribe" title="A simple synchronous publish and subscribe">A simple synchronous publish and subscribe</a></li><li><a href="#a-simple-asynchronous-publish-and-subscribe" title="A simple asynchronous publish and subscribe">A simple asynchronous publish and subscribe</a></li><li><a href="#important-notes" title="Important notes">Important notes</a></li><li><a href="#faq" title="FAQ">FAQ</a></li></ul><h3><a href="#reexports">Crate Items</a></h3><ul class="block"><li><a href="#reexports" title="Re-exports">Re-exports</a></li><li><a href="#modules" title="Modules">Modules</a></li><li><a href="#structs" title="Structs">Structs</a></li><li><a href="#enums" title="Enums">Enums</a></li><li><a href="#types" title="Type Aliases">Type Aliases</a></li></ul></section><div id="rustdoc-modnav"></div></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><div class="width-limiter"><section id="main-content" class="content"><div class="main-heading"><h1>Crate <span>rumqttc</span> <button id="copy-path" title="Copy item path to clipboard">Copy item path</button></h1><rustdoc-toolbar></rustdoc-toolbar><span class="sub-heading"><a class="src" href="../src/rumqttc/lib.rs.html#1-1016">Source</a> </span></div><details class="toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>A pure rust MQTT client which strives to be robust, efficient and easy to use.
|
||
This library is backed by an async (tokio) eventloop which handles all the
|
||
robustness and and efficiency parts of MQTT but naturally fits into both sync
|
||
and async worlds as we’ll see</p>
|
||
<p>Let’s jump into examples right away</p>
|
||
<h3 id="a-simple-synchronous-publish-and-subscribe"><a class="doc-anchor" href="#a-simple-synchronous-publish-and-subscribe">§</a>A simple synchronous publish and subscribe</h3>
|
||
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>rumqttc::{MqttOptions, Client, QoS};
|
||
<span class="kw">use </span>std::time::Duration;
|
||
<span class="kw">use </span>std::thread;
|
||
|
||
<span class="kw">let </span><span class="kw-2">mut </span>mqttoptions = MqttOptions::new(<span class="string">"rumqtt-sync"</span>, <span class="string">"test.mosquitto.org"</span>, <span class="number">1883</span>);
|
||
mqttoptions.set_keep_alive(Duration::from_secs(<span class="number">5</span>));
|
||
|
||
<span class="kw">let </span>(<span class="kw-2">mut </span>client, <span class="kw-2">mut </span>connection) = Client::new(mqttoptions, <span class="number">10</span>);
|
||
client.subscribe(<span class="string">"hello/rumqtt"</span>, QoS::AtMostOnce).unwrap();
|
||
thread::spawn(<span class="kw">move </span>|| <span class="kw">for </span>i <span class="kw">in </span><span class="number">0</span>..<span class="number">10 </span>{
|
||
client.publish(<span class="string">"hello/rumqtt"</span>, QoS::AtLeastOnce, <span class="bool-val">false</span>, <span class="macro">vec!</span>[i; i <span class="kw">as </span>usize]).unwrap();
|
||
thread::sleep(Duration::from_millis(<span class="number">100</span>));
|
||
});
|
||
|
||
<span class="comment">// Iterate to poll the eventloop for connection progress
|
||
</span><span class="kw">for </span>(i, notification) <span class="kw">in </span>connection.iter().enumerate() {
|
||
<span class="macro">println!</span>(<span class="string">"Notification = {:?}"</span>, notification);
|
||
}</code></pre></div><h3 id="a-simple-asynchronous-publish-and-subscribe"><a class="doc-anchor" href="#a-simple-asynchronous-publish-and-subscribe">§</a>A simple asynchronous publish and subscribe</h3>
|
||
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>rumqttc::{MqttOptions, AsyncClient, QoS};
|
||
<span class="kw">use </span>tokio::{task, time};
|
||
<span class="kw">use </span>std::time::Duration;
|
||
<span class="kw">use </span>std::error::Error;
|
||
|
||
<span class="kw">let </span><span class="kw-2">mut </span>mqttoptions = MqttOptions::new(<span class="string">"rumqtt-async"</span>, <span class="string">"test.mosquitto.org"</span>, <span class="number">1883</span>);
|
||
mqttoptions.set_keep_alive(Duration::from_secs(<span class="number">5</span>));
|
||
|
||
<span class="kw">let </span>(<span class="kw-2">mut </span>client, <span class="kw-2">mut </span>eventloop) = AsyncClient::new(mqttoptions, <span class="number">10</span>);
|
||
client.subscribe(<span class="string">"hello/rumqtt"</span>, QoS::AtMostOnce).<span class="kw">await</span>.unwrap();
|
||
|
||
task::spawn(<span class="kw">async move </span>{
|
||
<span class="kw">for </span>i <span class="kw">in </span><span class="number">0</span>..<span class="number">10 </span>{
|
||
client.publish(<span class="string">"hello/rumqtt"</span>, QoS::AtLeastOnce, <span class="bool-val">false</span>, <span class="macro">vec!</span>[i; i <span class="kw">as </span>usize]).<span class="kw">await</span>.unwrap();
|
||
time::sleep(Duration::from_millis(<span class="number">100</span>)).<span class="kw">await</span>;
|
||
}
|
||
});
|
||
|
||
<span class="kw">loop </span>{
|
||
<span class="kw">let </span>notification = eventloop.poll().<span class="kw">await</span>.unwrap();
|
||
<span class="macro">println!</span>(<span class="string">"Received = {:?}"</span>, notification);
|
||
}</code></pre></div>
|
||
<p>Quick overview of features</p>
|
||
<ul>
|
||
<li>Eventloop orchestrates outgoing/incoming packets concurrently and handles the state</li>
|
||
<li>Pings the broker when necessary and detects client side half open connections as well</li>
|
||
<li>Throttling of outgoing packets (todo)</li>
|
||
<li>Queue size based flow control on outgoing packets</li>
|
||
<li>Automatic reconnections by just continuing the <code>eventloop.poll()</code>/<code>connection.iter()</code> loop</li>
|
||
<li>Natural backpressure to client APIs during bad network</li>
|
||
</ul>
|
||
<p>In short, everything necessary to maintain a robust connection</p>
|
||
<p>Since the eventloop is externally polled (with <code>iter()/poll()</code> in a loop)
|
||
out side the library and <code>Eventloop</code> is accessible, users can</p>
|
||
<ul>
|
||
<li>Distribute incoming messages based on topics</li>
|
||
<li>Stop it when required</li>
|
||
<li>Access internal state for use cases like graceful shutdown or to modify options before reconnection</li>
|
||
</ul>
|
||
<h3 id="important-notes"><a class="doc-anchor" href="#important-notes">§</a>Important notes</h3>
|
||
<ul>
|
||
<li>
|
||
<p>Looping on <code>connection.iter()</code>/<code>eventloop.poll()</code> is necessary to run the
|
||
event loop and make progress. It yields incoming and outgoing activity
|
||
notifications which allows customization as you see fit.</p>
|
||
</li>
|
||
<li>
|
||
<p>Blocking inside the <code>connection.iter()</code>/<code>eventloop.poll()</code> loop will block
|
||
connection progress.</p>
|
||
</li>
|
||
</ul>
|
||
<h3 id="faq"><a class="doc-anchor" href="#faq">§</a>FAQ</h3>
|
||
<p><strong>Connecting to a broker using raw ip doesn’t work</strong></p>
|
||
<p>You cannot create a TLS connection to a bare IP address with a self-signed
|
||
certificate. This is a <a href="https://github.com/ctz/rustls/issues/184">limitation of rustls</a>.
|
||
One workaround, which only works under *nix/BSD-like systems, is to add an
|
||
entry to wherever your DNS resolver looks (e.g. <code>/etc/hosts</code>) for the bare IP
|
||
address and use that name in your code.</p>
|
||
</div></details><h2 id="reexports" class="section-header">Re-exports<a href="#reexports" class="anchor">§</a></h2><dl class="item-table reexports"><dt id="reexport.tokio_rustls"><code>pub use tokio_rustls;</code></dt><dt><code>pub use mqttbytes::<a class="mod" href="mqttbytes/v4/index.html" title="mod rumqttc::mqttbytes::v4">v4</a>::*;</code></dt><dt><code>pub use <a class="mod" href="mqttbytes/index.html" title="mod rumqttc::mqttbytes">mqttbytes</a>::*;</code></dt></dl><h2 id="modules" class="section-header">Modules<a href="#modules" class="anchor">§</a></h2><dl class="item-table"><dt><a class="mod" href="mqttbytes/index.html" title="mod rumqttc::mqttbytes">mqttbytes</a></dt><dd>mqttbytes</dd><dt><a class="mod" href="v5/index.html" title="mod rumqttc::v5">v5</a></dt></dl><h2 id="structs" class="section-header">Structs<a href="#structs" class="anchor">§</a></h2><dl class="item-table"><dt><a class="struct" href="struct.AsyncClient.html" title="struct rumqttc::AsyncClient">Async<wbr>Client</a></dt><dd>An asynchronous client, communicates with MQTT <code>EventLoop</code>.</dd><dt><a class="struct" href="struct.Client.html" title="struct rumqttc::Client">Client</a></dt><dd>A synchronous client, communicates with MQTT <code>EventLoop</code>.</dd><dt><a class="struct" href="struct.Connection.html" title="struct rumqttc::Connection">Connection</a></dt><dd>MQTT connection. Maintains all the necessary state</dd><dt><a class="struct" href="struct.EventLoop.html" title="struct rumqttc::EventLoop">Event<wbr>Loop</a></dt><dd>Eventloop with all the state of a connection</dd><dt><a class="struct" href="struct.Iter.html" title="struct rumqttc::Iter">Iter</a></dt><dd>Iterator which polls the <code>EventLoop</code> for connection progress</dd><dt><a class="struct" href="struct.MqttOptions.html" title="struct rumqttc::MqttOptions">Mqtt<wbr>Options</a></dt><dd>Options to configure the behaviour of MQTT connection</dd><dt><a class="struct" href="struct.MqttState.html" title="struct rumqttc::MqttState">Mqtt<wbr>State</a></dt><dd>State of the mqtt connection.</dd><dt><a class="struct" href="struct.NetworkOptions.html" title="struct rumqttc::NetworkOptions">Network<wbr>Options</a></dt><dd>Provides a way to configure low level network connection configurations</dd><dt><a class="struct" href="struct.RecvError.html" title="struct rumqttc::RecvError">Recv<wbr>Error</a></dt><dd>Error type returned by <a href="struct.Connection.html#method.recv" title="method rumqttc::Connection::recv"><code>Connection::recv</code></a></dd></dl><h2 id="enums" class="section-header">Enums<a href="#enums" class="anchor">§</a></h2><dl class="item-table"><dt><a class="enum" href="enum.ClientError.html" title="enum rumqttc::ClientError">Client<wbr>Error</a></dt><dd>Client Error</dd><dt><a class="enum" href="enum.ConnectionError.html" title="enum rumqttc::ConnectionError">Connection<wbr>Error</a></dt><dd>Critical errors during eventloop polling</dd><dt><a class="enum" href="enum.Event.html" title="enum rumqttc::Event">Event</a></dt><dd>Events which can be yielded by the event loop</dd><dt><a class="enum" href="enum.Outgoing.html" title="enum rumqttc::Outgoing">Outgoing</a></dt><dd>Current outgoing activity on the eventloop</dd><dt><a class="enum" href="enum.RecvTimeoutError.html" title="enum rumqttc::RecvTimeoutError">Recv<wbr>Timeout<wbr>Error</a></dt><dd>Error type returned by <a href="struct.Connection.html#method.recv_timeout" title="method rumqttc::Connection::recv_timeout"><code>Connection::recv_timeout</code></a></dd><dt><a class="enum" href="enum.Request.html" title="enum rumqttc::Request">Request</a></dt><dd>Requests by the client to mqtt event loop. Request are
|
||
handled one by one.</dd><dt><a class="enum" href="enum.StateError.html" title="enum rumqttc::StateError">State<wbr>Error</a></dt><dd>Errors during state handling</dd><dt><a class="enum" href="enum.TlsConfiguration.html" title="enum rumqttc::TlsConfiguration">TlsConfiguration</a></dt><dd>TLS configuration method</dd><dt><a class="enum" href="enum.TlsError.html" title="enum rumqttc::TlsError">TlsError</a></dt><dt><a class="enum" href="enum.Transport.html" title="enum rumqttc::Transport">Transport</a></dt><dd>Transport methods. Defaults to TCP.</dd><dt><a class="enum" href="enum.TryRecvError.html" title="enum rumqttc::TryRecvError">TryRecv<wbr>Error</a></dt><dd>Error type returned by <a href="struct.Connection.html#method.try_recv" title="method rumqttc::Connection::try_recv"><code>Connection::try_recv</code></a></dd></dl><h2 id="types" class="section-header">Type Aliases<a href="#types" class="anchor">§</a></h2><dl class="item-table"><dt><a class="type" href="type.Incoming.html" title="type rumqttc::Incoming">Incoming</a></dt></dl></section></div></main></body></html> |