<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: DeviceShelf</title>
    <description>The latest articles on DEV Community by DeviceShelf (@deviceshelf).</description>
    <link>https://dev.to/deviceshelf</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4022828%2F92dc3100-4e93-49c8-b92e-e8436b77eb76.png</url>
      <title>DEV Community: DeviceShelf</title>
      <link>https://dev.to/deviceshelf</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/deviceshelf"/>
    <language>en</language>
    <item>
      <title>Test an MQTT Payload Filter in Home Assistant Before Using It for an Alert</title>
      <dc:creator>DeviceShelf</dc:creator>
      <pubDate>Mon, 09 Nov 2026 10:00:06 +0000</pubDate>
      <link>https://dev.to/deviceshelf/test-an-mqtt-payload-filter-in-home-assistant-before-using-it-for-an-alert-2jaa</link>
      <guid>https://dev.to/deviceshelf/test-an-mqtt-payload-filter-in-home-assistant-before-using-it-for-an-alert-2jaa</guid>
      <description>&lt;p&gt;Liquid syntax error: 'raw' tag was never closed&lt;/p&gt;
</description>
      <category>tutorial</category>
      <category>networking</category>
      <category>homelab</category>
      <category>selfhosted</category>
    </item>
    <item>
      <title>Verify a Home Assistant Automation Action With a Persistent Notification</title>
      <dc:creator>DeviceShelf</dc:creator>
      <pubDate>Sat, 07 Nov 2026 10:00:05 +0000</pubDate>
      <link>https://dev.to/deviceshelf/verify-a-home-assistant-automation-action-with-a-persistent-notification-1ika</link>
      <guid>https://dev.to/deviceshelf/verify-a-home-assistant-automation-action-with-a-persistent-notification-1ika</guid>
      <description>&lt;p&gt;Liquid syntax error: 'raw' tag was never closed&lt;/p&gt;
</description>
      <category>tutorial</category>
      <category>networking</category>
      <category>homelab</category>
      <category>selfhosted</category>
    </item>
    <item>
      <title>How to Read a Home Assistant Automation Trace After an MQTT Test</title>
      <dc:creator>DeviceShelf</dc:creator>
      <pubDate>Thu, 05 Nov 2026 10:00:06 +0000</pubDate>
      <link>https://dev.to/deviceshelf/how-to-read-a-home-assistant-automation-trace-after-an-mqtt-test-3o40</link>
      <guid>https://dev.to/deviceshelf/how-to-read-a-home-assistant-automation-trace-after-an-mqtt-test-3o40</guid>
      <description>&lt;p&gt;Liquid syntax error: 'raw' tag was never closed&lt;/p&gt;
</description>
      <category>tutorial</category>
      <category>networking</category>
      <category>homelab</category>
      <category>selfhosted</category>
    </item>
    <item>
      <title>MQTT Sessions After a Reconnect: Check What the Broker Can Replay</title>
      <dc:creator>DeviceShelf</dc:creator>
      <pubDate>Tue, 03 Nov 2026 10:00:06 +0000</pubDate>
      <link>https://dev.to/deviceshelf/mqtt-sessions-after-a-reconnect-check-what-the-broker-can-replay-5929</link>
      <guid>https://dev.to/deviceshelf/mqtt-sessions-after-a-reconnect-check-what-the-broker-can-replay-5929</guid>
      <description>&lt;p&gt;An MQTT client doesn't necessarily come back to an empty inbox when it reconnects. Depending on the connection and subscription settings, the broker can keep session information and deliver messages queued while the client was away. A retained message can arrive when a client subscribes, too. Both behaviors are useful, but neither proves that a device just produced a new event.&lt;/p&gt;

&lt;p&gt;This matters when a Home Assistant automation reacts to a message after a restart, network interruption, or broker maintenance. The notification might reflect a fresh measurement. It might also be a replay from an earlier session or retained state arriving at the subscriber. The lab check below helps you tell those cases apart instead of guessing from a dashboard timestamp. It doesn't establish whether a real device, NAS, or service is healthy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Session state and retained state
&lt;/h2&gt;

&lt;p&gt;MQTT sessions and retained messages are different features. A session can hold information about a client connection, including subscriptions and, depending on quality of service and session settings, messages waiting for delivery. A retained message is stored by the broker for a topic and can be sent to a later subscriber. The &lt;a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html" rel="noopener noreferrer"&gt;MQTT Version 5.0 specification&lt;/a&gt; defines the protocol details.&lt;/p&gt;

&lt;p&gt;A message arriving after reconnect doesn't tell you why it arrived. The payload can look exactly the same whether it was published moments ago or delivered from state the broker kept. Topic names don't prove anything either. A topic called &lt;code&gt;online&lt;/code&gt;, &lt;code&gt;event&lt;/code&gt;, or &lt;code&gt;current&lt;/code&gt; means only what its publisher and consumers agree it means.&lt;/p&gt;

&lt;p&gt;Before testing, write down four facts for one lab path: which client will disconnect, the exact topic, the QoS chosen by the publisher and subscriber, and whether the publisher uses the retain flag. Include the connection's session behavior if you control it. Avoid wildcard subscriptions. Don't use a command topic. Don't include credentials, actual device identifiers, or private addresses in test topic names, payloads, or shared records.&lt;/p&gt;

&lt;h2&gt;
  
  
  A dedicated lab topic
&lt;/h2&gt;

&lt;p&gt;Use a broker and Home Assistant instance you administer. Create a clearly temporary topic, such as &lt;code&gt;lab/session-replay-2026-10-28/event&lt;/code&gt;, with one known test publisher and one known subscriber. The subscriber can be a Home Assistant MQTT trigger or a separate diagnostic client. Choose a path that lets you record the topic, payload, receive time, and retain indicator. Before each independent run, clear any retained lab message by publishing a zero-length payload with the retain flag enabled on that exact test topic. Complete this reset before recording observations. Use test payloads unique to each run; don't reuse the example values below in later runs.&lt;/p&gt;

&lt;p&gt;With the subscriber connected, have the publisher send a distinct value, for example &lt;code&gt;run-a&lt;/code&gt;. Record what arrives, then disconnect the subscriber. While it's disconnected, publish a second distinct value, &lt;code&gt;run-b&lt;/code&gt;, using your chosen QoS and retain setting. Change no more than one setting per run. Receiving &lt;code&gt;run-b&lt;/code&gt; after reconnect tells you something, but you still need to classify the delivery.&lt;/p&gt;

&lt;p&gt;For the session continuation run, keep the same client ID and record the Session Present flag in CONNACK after reconnect. Repeat the run with a deliberately clean or expired session if your broker and client configuration support it. After starting a new session, resubscribe to the lab topic because the previous subscriptions are no longer present. Record whether the client automatically resubscribes and, for MQTT 5 where applicable, the subscription's Retain Handling setting, since retained delivery depends on subscribing and the subscription options. Then repeat with retain disabled and enabled, changing only that variable. These small comparisons tell you more than restarting several services at once. A restart can erase the event order that would explain the result.&lt;/p&gt;

&lt;h2&gt;
  
  
  Broker observations and subscriber results
&lt;/h2&gt;

&lt;p&gt;Use the broker's log, or an administrative observation available in your test environment, to record connects, disconnects, subscriptions, and publications. Don't assume the user interface shows every broker-side detail. The MQTT protocol specifies how packets and sessions behave; the broker implementation decides how those details appear in its diagnostics.&lt;/p&gt;

&lt;p&gt;Make a small table for each run with the connection time, session choice, publication time, retain flag, subscriber receive time, and received value. Label each row as an observation, not a conclusion. For example, “subscriber received &lt;code&gt;run-b&lt;/code&gt; after reconnect” is supportable. “The device sent a new event after reconnect” isn't, unless the publisher's own fresh measurement and timestamp establish that fact.&lt;/p&gt;

&lt;p&gt;If the result changes when you toggle only retain, investigate retained delivery as the leading explanation. If it changes only with the session setting, look into session continuation and queued delivery. If neither changes the result, check spelling, case, authentication, ACLs, QoS, and the exact subscription filter before drawing a broader conclusion.&lt;/p&gt;

&lt;h2&gt;
  
  
  A harmless Home Assistant automation
&lt;/h2&gt;

&lt;p&gt;Home Assistant can react directly to an MQTT message. Its MQTT integration also has its own connection and discovery behavior. &lt;a href="https://www.home-assistant.io/integrations/mqtt/" rel="noopener noreferrer"&gt;The MQTT integration documentation&lt;/a&gt; and the &lt;a href="https://www.home-assistant.io/docs/automation/trigger/" rel="noopener noreferrer"&gt;automation trigger reference&lt;/a&gt; distinguish integration setup from an automation's trigger configuration. A successful connection doesn't tell you whether a particular rule received the intended message.&lt;/p&gt;

&lt;p&gt;Create a temporary automation for the lab topic. For the first test, have it add a persistent notification, write a logbook entry, or update a dedicated helper. Don't publish a command, restart a host, switch power, or change a network setting. Send the two lab values through the controlled sequence. Then inspect the automation trace and the harmless result.&lt;/p&gt;

&lt;p&gt;The trace answers a limited question: did this configured rule enter its trigger and complete its configured path? It doesn't prove when a real device event happened or where it came from. Home Assistant's &lt;a href="https://www.home-assistant.io/docs/automation/troubleshooting/" rel="noopener noreferrer"&gt;automation troubleshooting guidance&lt;/a&gt; helps distinguish a trigger that never fired from a condition or action that prevented the expected result.&lt;/p&gt;

&lt;p&gt;If the automation fires twice, resist adding a delay or suppression rule straight away. Compare both trace times with the broker observation and the lab table. The cause could be a repeated publisher event, retained delivery, two subscriptions, or a reconnect effect. Hiding the second notification with a workaround can also hide the evidence you need to diagnose the path.&lt;/p&gt;

&lt;h2&gt;
  
  
  Discovery, availability, and fresh events
&lt;/h2&gt;

&lt;p&gt;MQTT discovery can create or update a Home Assistant entity after configuration is published. That's separate from a state message, and a replayed message is another matter again. &lt;a href="https://www.home-assistant.io/integrations/mqtt/#mqtt-discovery" rel="noopener noreferrer"&gt;Home Assistant's discovery documentation&lt;/a&gt; explains the configuration path. Before treating an entity change as evidence in a session test, confirm the entity's unique ID and state topic.&lt;/p&gt;

&lt;p&gt;An availability topic is a separate signal as well. It may describe the publisher's declared connection state according to its configuration, but it doesn't test every service that publisher represents. A NAS, for example, can be connected to the broker while a file share is unavailable. Record availability transitions and received events in separate columns.&lt;/p&gt;

&lt;p&gt;DeviceShelf Server can provide network observations through MQTT discovery to a Home Assistant installation you administer. You can compare an observation with broker and service records. It doesn't prove what caused a broker replay, establish a device's identity or availability, or show that an automation action succeeded.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cleanup and a bounded conclusion
&lt;/h2&gt;

&lt;p&gt;After the test, disable or remove the temporary automation. Clear any retained lab message you created, and verify that no test topic can affect a production action. Keep the non-sensitive record of the test settings, message order, broker observation, and trace result. That gives you something to compare with a later incident without treating the lab result as if it covers every client.&lt;/p&gt;

&lt;p&gt;Keep the conclusion narrow: under the recorded session and retain settings, the lab subscriber received a specific value after reconnect, and the temporary automation recorded it once or twice. If the origin is still uncertain, check the relevant publisher and broker logs before changing a production alert. The test should give you a concrete next check. One MQTT delivery isn't a health guarantee.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources checked
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html" rel="noopener noreferrer"&gt;OASIS MQTT Version 5.0 specification&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.home-assistant.io/integrations/mqtt/" rel="noopener noreferrer"&gt;Home Assistant MQTT integration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.home-assistant.io/integrations/mqtt/#mqtt-discovery" rel="noopener noreferrer"&gt;Home Assistant MQTT discovery&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.home-assistant.io/docs/automation/trigger/" rel="noopener noreferrer"&gt;Home Assistant automation triggers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.home-assistant.io/docs/automation/troubleshooting/" rel="noopener noreferrer"&gt;Home Assistant automation troubleshooting&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://deviceshelf.app/server" rel="noopener noreferrer"&gt;DeviceShelf Server documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>tutorial</category>
      <category>networking</category>
      <category>homelab</category>
      <category>selfhosted</category>
    </item>
    <item>
      <title>Test an MQTT Automation With a Fictional Event Before Relying on It</title>
      <dc:creator>DeviceShelf</dc:creator>
      <pubDate>Sun, 01 Nov 2026 10:00:07 +0000</pubDate>
      <link>https://dev.to/deviceshelf/test-an-mqtt-automation-with-a-fictional-event-before-relying-on-it-1ipb</link>
      <guid>https://dev.to/deviceshelf/test-an-mqtt-automation-with-a-fictional-event-before-relying-on-it-1ipb</guid>
      <description>&lt;p&gt;An MQTT automation can look finished before it has processed a single message from a broker. The YAML saves, a manual action produces a notification, and the dashboard looks right. That's useful to know. But none of it proves that the topic, payload filter, template, and action work together when a publisher sends an event.&lt;/p&gt;

&lt;p&gt;A small fictional event makes a better first test. Use a topic reserved for testing, data that identifies no real person or device, and a harmless action you can see. The question is narrow: did this automation process this message at this time? A passing test does not prove that a device is present, that a scanner will always find it, or that MQTT will deliver every future message.&lt;/p&gt;

&lt;p&gt;These examples use Home Assistant, but the distinction between checking the editor, running an action manually, and testing the event path applies to any MQTT consumer. Use only a broker and automation you administer.&lt;/p&gt;

&lt;h2&gt;
  
  
  A clear claim before editing
&lt;/h2&gt;

&lt;p&gt;Write down the result you need in one sentence. For example: a JSON message on lab/automation-test/2026-10-31/event whose event type is new_device creates one persistent notification. That statement names a topic, a payload field, a matching value, and an action you can observe. It's much easier to test than a vague claim that MQTT works.&lt;/p&gt;

&lt;p&gt;Keep the related claims separate. A successful fictional message proves a path from a known publisher through a broker to one automation. It does not identify a real device, establish an intrusion, or guarantee exactly-once delivery. If you're trying to decide whether a device needs investigation, record independent observations first. &lt;a href="https://deviceshelf.app/blog/2026-09-18-see-all-devices-on-network/" rel="noopener noreferrer"&gt;How to See Every Device on Your Network and Find Its IP Address&lt;/a&gt; explains how to compare an inventory with router information without treating a name as an identity.&lt;/p&gt;

&lt;p&gt;Choose a safe first action. Use a persistent notification, logbook entry, or dedicated helper rather than changing a switch, lock, alarm, or network setting. A notification also gives you a timestamp to compare with the automation trace.&lt;/p&gt;

&lt;h2&gt;
  
  
  A distinct test topic
&lt;/h2&gt;

&lt;p&gt;Create a topic under a prefix you control and include a date or test identifier. For example, use lab/automation-test/2026-10-31/event. It's easy to spot in a broker log and unlikely to collide with a live integration. You can remove it easily later.&lt;/p&gt;

&lt;p&gt;Avoid any topic associated with an action that has real consequences. Keep real credentials, private addresses, customer names, and live device identifiers out of the sample. Clearly fictional data makes the test easier to repeat and review.&lt;/p&gt;

&lt;p&gt;MQTT matching is exact unless you've explicitly configured wildcards. That final s matters: lab/automation-test/2026-10-31/event and lab/automation-test/2026-10-31/events are different topics. Uppercase and lowercase letters differ too. If a trigger doesn't fire, compare the publisher's topic with the trigger's topic character by character before changing anything else.&lt;/p&gt;

&lt;h2&gt;
  
  
  An automation with a narrow match
&lt;/h2&gt;

&lt;p&gt;This is a single Home Assistant automation for the YAML editor, not a full configuration.yaml file. It listens to the test-only topic and accepts only a JSON event whose event_type is new_device.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;alias&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;MQTT fictional-event check&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Confirm that one test-only MQTT message reaches this automation.&lt;/span&gt;
&lt;span class="na"&gt;triggers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;trigger&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mqtt&lt;/span&gt;
    &lt;span class="na"&gt;topic&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lab/automation-test/2026-10-31/event&lt;/span&gt;
    &lt;span class="na"&gt;value_template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;(value_json.event_type&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;|&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;default(''))&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;if&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;value_json&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;is&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;defined&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;value_json&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;is&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;mapping&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;else&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;''&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;
    &lt;span class="na"&gt;payload&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;new_device&lt;/span&gt;
&lt;span class="na"&gt;conditions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[]&lt;/span&gt;
&lt;span class="na"&gt;actions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;persistent_notification.create&lt;/span&gt;
    &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;notification_id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mqtt_fictional_event_check&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;MQTT test received&lt;/span&gt;
      &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;&amp;gt;-&lt;/span&gt;
        &lt;span class="s"&gt;Received the fictional event for&lt;/span&gt;
        &lt;span class="s"&gt;{{ trigger.payload_json.name | default('unnamed example', true) }}.&lt;/span&gt;
&lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;single&lt;/span&gt;
&lt;span class="s"&gt;~~~&lt;/span&gt;

&lt;span class="s"&gt;The value template extracts event_type, and the payload condition compares it with new_device. Invalid JSON or a missing field becomes an empty value and does not match. That's intentional&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;the test should fail clearly, without letting an unrelated message look like a success.&lt;/span&gt;

&lt;span class="s"&gt;Save the automation and check that it's enabled. To check whether the notification service itself works, call persistent_notification.create separately with a literal message such as "MQTT notification test". Home Assistant's Run actions control supplies no trigger data, so the supplied automation's message template can fail when run manually. Test this automation by publishing MQTT; a successful separate service call is not evidence that a broker message reached the automation.&lt;/span&gt;

&lt;span class="c1"&gt;## Publication of one fictional message&lt;/span&gt;

&lt;span class="s"&gt;Use Home Assistant's MQTT Publish a packet tool or another publisher connected to the same broker. Leave retain off. Publish once to the exact test topic with this payload:&lt;/span&gt;

&lt;span class="s"&gt;~~~json&lt;/span&gt;
&lt;span class="pi"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;event_type"&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;new_device"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name"&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Tutorial&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;printer"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ip"&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;192.0.2.42"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;note"&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fictional&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;test&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;data"&lt;/span&gt;
&lt;span class="pi"&gt;}&lt;/span&gt;
&lt;span class="s"&gt;~~~&lt;/span&gt;

&lt;span class="s"&gt;The address 192.0.2.42 is documentation space, not a host to contact. Tutorial printer is fictional too. This payload tests the structure the trigger expects; it does not claim to report a live network change.&lt;/span&gt;

&lt;span class="s"&gt;After publishing, check for the persistent notification, then look for a new automation trace matching the publication time. Record the publication time and topic along with the trace run and action result. A new trace showing the trigger data and notification action result tells you more than an editor screenshot.&lt;/span&gt;

&lt;span class="s"&gt;If no notification appears, check in this order&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;

&lt;span class="s"&gt;1. Confirm that the automation is saved and enabled.&lt;/span&gt;
&lt;span class="s"&gt;2. Compare the publisher and trigger topics exactly.&lt;/span&gt;
&lt;span class="s"&gt;3. Confirm that Home Assistant and the publisher use the intended broker.&lt;/span&gt;
&lt;span class="s"&gt;4. Check that the payload is valid JSON and event_type is exactly new_device.&lt;/span&gt;
&lt;span class="s"&gt;5. Look for a new trace matching the publication time before editing. If none exists, check MQTT reception and filtering; a message that does not trigger the automation produces no new run trace. If one exists, inspect its trigger data and action result.&lt;/span&gt;

&lt;span class="s"&gt;Change one variable at a time. If you replace the broker, topic, trigger, and payload together, you've created a new test whose result you can't interpret.&lt;/span&gt;

&lt;span class="c1"&gt;## A negative check&lt;/span&gt;

&lt;span class="s"&gt;Publish a second fictional message to the same topic, this time with an event type that should not match:&lt;/span&gt;

&lt;span class="s"&gt;~~~json&lt;/span&gt;
&lt;span class="pi"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;event_type"&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;device_offline"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name"&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Tutorial&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;printer"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;note"&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fictional&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;negative&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;test"&lt;/span&gt;&lt;span class="pi"&gt;}&lt;/span&gt;
&lt;span class="s"&gt;~~~&lt;/span&gt;

&lt;span class="s"&gt;The automation should not run. Without this check, the first notification might only tell you that the subscription is broad. That first result alone doesn't establish that the filter rejects unrelated events.&lt;/span&gt;

&lt;span class="s"&gt;Avoid retained messages for this event test. A broker may send a retained message to a subscriber that connects later. That's useful for current state, but misleading if you're checking whether an event happened after the receiver was ready. If the test topic already has retained state, isolate or clear it using the broker's documented procedure before interpreting the next run.&lt;/span&gt;

&lt;span class="c1"&gt;## Restarts as a separate test&lt;/span&gt;

&lt;span class="s"&gt;Once the positive and negative checks work, a restart can answer a different question&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;what happens when the receiver is unavailable? Restart the automation or Home Assistant during a safe maintenance window, then inspect the trace timestamps. An old notification may still be visible. That should not turn an earlier non-retained event into a fresh event.&lt;/span&gt;

&lt;span class="s"&gt;Availability topics need their own test. A configured online or offline value tells you how Home Assistant interpreted a message on that topic, but not why a publisher, service, or device became unavailable. Test availability transitions separately from event handling. Keep a note of whether the message was retained.&lt;/span&gt;

&lt;span class="c1"&gt;## The move to a real integration&lt;/span&gt;

&lt;span class="s"&gt;Wait until the isolated topic works before adapting the automation to a real publisher. Keep the first production action observational. A notification asking someone to compare an inventory is safer than automatic labeling or a network change.&lt;/span&gt;

&lt;span class="s"&gt;DeviceShelf Server is one possible publisher of local network observations through MQTT discovery. You should still compare its output with router records and known-device information. A message is not proof of device identity, availability, delivery, or an intrusion.&lt;/span&gt;

&lt;span class="s"&gt;Keep a short test record with the reserved topic, fictional payload, publication time, trace result, and any change you made because of the trace. This gives you a repeatable baseline for later troubleshooting. Remove the test-only automation, helper, and retained test state once they're no longer useful.&lt;/span&gt;

&lt;span class="na"&gt;A passing test establishes one limited but useful fact&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;a known broker accepted one fictional message, and this automation processed it as configured. It doesn't measure reliability over time or replace incident review. Keeping that limit clear is the point of the exercise. A calm, repeatable test is much more useful than guessing during a real outage or an unexpected device event.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>tutorial</category>
      <category>networking</category>
      <category>homelab</category>
      <category>selfhosted</category>
    </item>
    <item>
      <title>Validate a JSON MQTT Payload Before Using It in a Home Assistant Automation</title>
      <dc:creator>DeviceShelf</dc:creator>
      <pubDate>Fri, 30 Oct 2026 10:00:07 +0000</pubDate>
      <link>https://dev.to/deviceshelf/validate-a-json-mqtt-payload-before-using-it-in-a-home-assistant-automation-5h40</link>
      <guid>https://dev.to/deviceshelf/validate-a-json-mqtt-payload-before-using-it-in-a-home-assistant-automation-5h40</guid>
      <description>&lt;p&gt;An MQTT message can look like JSON and still be unsafe input for an automation. It might be malformed, arrive on the wrong topic, or be retained from an earlier test. Even valid JSON can contain a field whose meaning has changed. A rule may react to any of these messages without receiving the event it was supposed to handle.&lt;/p&gt;

&lt;p&gt;Start with a smaller question than “does MQTT work?”: can a Home Assistant rule receive one controlled JSON message, extract the intended value, and make one harmless change you can observe? This guide walks through that check on a broker and Home Assistant installation you administer. The test won't establish whether a real device is online, a sensor reading is accurate, or a production action should run.&lt;/p&gt;

&lt;h2&gt;
  
  
  A single purpose for the test
&lt;/h2&gt;

&lt;p&gt;Decide what the automation needs from the payload before you create a trigger. A small lab message such as &lt;code&gt;{"event":"check","sequence":1}&lt;/code&gt; lets you check whether the message parses as JSON and whether the expected &lt;code&gt;event&lt;/code&gt; field contains the expected value. That's all it proves. It cannot show that a device produced a fresh measurement. Keep credentials, full network inventories, MAC addresses, private IP addresses, and personal names out of the test payload.&lt;/p&gt;

&lt;p&gt;Pick a temporary topic that no existing publisher or rule uses, for example &lt;code&gt;lab/json-payload-check-2026-10-29/event&lt;/code&gt;. Avoid wildcards and command topics. Write down the broker, exact topic, expected JSON shape, configured QoS, retain choice, and the entity or automation that will observe it. With that record, you can tell a topic error from a template error without changing several settings at once.&lt;/p&gt;

&lt;p&gt;The MQTT specification defines a message payload as application data. The publisher and consumer choose to use JSON; the broker doesn't add that property. The &lt;a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html" rel="noopener noreferrer"&gt;MQTT Version 5.0 specification&lt;/a&gt; provides background on topics and message delivery, but it doesn't define what a field named &lt;code&gt;event&lt;/code&gt; or &lt;code&gt;status&lt;/code&gt; means.&lt;/p&gt;

&lt;h2&gt;
  
  
  Topic checks before template checks
&lt;/h2&gt;

&lt;p&gt;First, confirm the exact topic path using a controlled publisher and a diagnostic subscriber in the test environment. Publish one clearly marked, fictional message. If it doesn't arrive, check the topic spelling, connection, authentication, and ACLs before adding a JSON template. Even a correct template won't help if the subscriber is listening on a different path.&lt;/p&gt;

&lt;p&gt;Next, publish one message with the intended shape and another with a deliberately different but still valid value, such as &lt;code&gt;{"event":"check","sequence":2}&lt;/code&gt;. Compare &lt;code&gt;sequence&lt;/code&gt; in the diagnostic subscriber’s raw payload to distinguish the two messages; a sensor extracting only &lt;code&gt;event&lt;/code&gt; will show &lt;code&gt;check&lt;/code&gt; for both. Keep the retain flag the same for both messages. Test retain behavior in a separate run if needed, and record it as a separate variable.&lt;/p&gt;

&lt;p&gt;Home Assistant documents MQTT connection and setup separately from MQTT sensors and automations. A connected integration tells you that Home Assistant can talk to the broker. It doesn't show that a particular configured topic, entity, or automation receives the intended data. The &lt;a href="https://www.home-assistant.io/integrations/mqtt/" rel="noopener noreferrer"&gt;Home Assistant MQTT integration documentation&lt;/a&gt; covers the integration-level configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  A focused MQTT sensor or trigger
&lt;/h2&gt;

&lt;p&gt;An MQTT sensor can expose a state topic and apply a value template when you want a state to inspect. If an event should start a rule, an MQTT trigger can listen to a topic and filter or template the received payload. Choose one of these paths for the lab run. Building a sensor, discovery configuration, and production automation at the same time makes it hard to tell which layer accepted the message.&lt;/p&gt;

&lt;p&gt;Extract only the JSON property you need for the check. If the rule should continue only when &lt;code&gt;event&lt;/code&gt; equals &lt;code&gt;check&lt;/code&gt;, compare that exact value. Parsing successfully isn't enough to accept a payload, and loosening the comparison just to make the test fire defeats the check. Case matters. So can whitespace inside a string, a missing field, or a changed type.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://www.home-assistant.io/integrations/sensor.mqtt/" rel="noopener noreferrer"&gt;MQTT sensor documentation&lt;/a&gt; covers state and value-template configuration. Follow the documented syntax for the Home Assistant version running in your test instance instead of copying a fragment from an unrelated integration. If a template renders an empty or unexpected value, investigate it. Publishing increasingly broad test data won't explain that observation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three controlled lab messages
&lt;/h2&gt;

&lt;p&gt;Use only a broker and topics you administer. This sequence keeps the results easy to follow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Publish a valid, clearly fictional message with the expected field and value, such as &lt;code&gt;{"event":"check","sequence":1}&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Publish a valid JSON message with a deliberately different &lt;code&gt;event&lt;/code&gt; value, such as &lt;code&gt;{"event":"ignore","sequence":2}&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Publish a malformed test string only if the diagnostic path can safely display it. Otherwise, stop after the first two messages and record that invalid-input handling was not tested.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;After each message, record its publish time, topic, retain choice, what the subscriber received, the extracted value, and whether the rule triggered. Pay attention to the second message. If the rule runs for both values, it isn't yet testing the intended event. The malformed case is optional because its effect depends on the Home Assistant configuration you've chosen. Never test a malformed payload against an automation that controls power, network configuration, locks, alarms, or another real-world action.&lt;/p&gt;

&lt;p&gt;A retained message isn't fresh just because its state becomes visible after subscription. When the run is complete, clear the retained lab value and confirm that the temporary topic cannot feed a permanent rule.&lt;/p&gt;

&lt;h2&gt;
  
  
  A reversible first action
&lt;/h2&gt;

&lt;p&gt;For the first successful match, make the automation action a persistent notification, a logbook entry, or a dedicated helper. Don't restart a NAS, publish a command, change a network setting, or notify a third party. Home Assistant's &lt;a href="https://www.home-assistant.io/docs/automation/trigger/" rel="noopener noreferrer"&gt;automation trigger reference&lt;/a&gt; explains MQTT triggers. Its &lt;a href="https://www.home-assistant.io/docs/automation/troubleshooting/" rel="noopener noreferrer"&gt;automation troubleshooting guidance&lt;/a&gt; helps you tell whether a trigger failed to run or a condition or action prevented the expected result.&lt;/p&gt;

&lt;p&gt;Inspect the automation trace after each test message. A trace for the expected message tells you something specific: this configuration entered its configured path for that lab input. It doesn't prove that a production publisher sends comparable data or that a device is healthy. Nor does it prove that a later notification reaches a person.&lt;/p&gt;

&lt;p&gt;No trace? Go back to the recorded topic and payload before editing the action. If there's a trace but no visible, harmless result, inspect the conditions and the selected action. Change one element and repeat one fictional input, keeping the result in the lab. That preserves evidence you would lose by changing several things and trying again.&lt;/p&gt;

&lt;h2&gt;
  
  
  JSON and other network evidence
&lt;/h2&gt;

&lt;p&gt;JSON can carry an identifier or an address. Neither proves a device's identity. Hostnames can change, private Wi-Fi addresses can rotate, and publishers can report old state. When an MQTT message concerns a network device, compare it with suitable independent records: the broker log, the publisher log, the router's active-client view, or a controlled local observation. Start with &lt;a href="https://deviceshelf.app/blog/2026-09-18-see-all-devices-on-network/" rel="noopener noreferrer"&gt;See All Devices on Your Network and Their IP Addresses&lt;/a&gt; if you need to distinguish a current network observation from a label in a message.&lt;/p&gt;

&lt;p&gt;DeviceShelf Server can provide network observations through MQTT discovery to a Home Assistant installation you administer. You can use it as one source to compare against the message path. It doesn't validate arbitrary JSON, prove a device's identity or availability, or prove that an automation completed successfully.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test cleanup and a limited conclusion
&lt;/h2&gt;

&lt;p&gt;After the run, disable or remove the temporary automation and clear any retained lab data you used. Keep only a non-sensitive record of the topic, sample shape, observation times, and trace result. Be specific about what worked: on the recorded test topic, the expected fictional JSON value was extracted and a harmless rule ran once; the different value did not pass the intended filter. If that didn't happen, find the first layer that behaved differently from what you expected before considering a more powerful action.&lt;/p&gt;

&lt;p&gt;This gives you a basis for assessing a later production change. It doesn't make an MQTT payload a health guarantee, a security finding, or evidence that every network device is correctly represented.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources checked
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html" rel="noopener noreferrer"&gt;OASIS MQTT Version 5.0 specification&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.home-assistant.io/integrations/mqtt/" rel="noopener noreferrer"&gt;Home Assistant MQTT integration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.home-assistant.io/integrations/sensor.mqtt/" rel="noopener noreferrer"&gt;Home Assistant MQTT sensor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.home-assistant.io/docs/automation/trigger/" rel="noopener noreferrer"&gt;Home Assistant automation triggers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.home-assistant.io/docs/automation/troubleshooting/" rel="noopener noreferrer"&gt;Home Assistant automation troubleshooting&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://deviceshelf.app/server" rel="noopener noreferrer"&gt;DeviceShelf Server documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>tutorial</category>
      <category>networking</category>
      <category>homelab</category>
      <category>selfhosted</category>
    </item>
    <item>
      <title>MQTT Birth Messages After a Restart: Check What Reconnected</title>
      <dc:creator>DeviceShelf</dc:creator>
      <pubDate>Wed, 28 Oct 2026 10:00:06 +0000</pubDate>
      <link>https://dev.to/deviceshelf/mqtt-birth-messages-after-a-restart-check-what-reconnected-29d1</link>
      <guid>https://dev.to/deviceshelf/mqtt-birth-messages-after-a-restart-check-what-reconnected-29d1</guid>
      <description>&lt;p&gt;After a broker or Home Assistant restart, it's tempting to take the first MQTT message as a sign that everything is back. Usually, it isn't. A client can reconnect while an entity is still unavailable. A retained state may be old, and an automation can be enabled without receiving the event it needs.&lt;/p&gt;

&lt;p&gt;A birth message gives you a defined marker: a client has connected and published a known payload. It doesn't tell you whether the whole system is healthy. This guide uses a small lab topic to check three things: whether Home Assistant reconnected, whether a known publisher reconnected, and whether a harmless automation observed the event. The result covers only the controlled path you test. It doesn't prove that a NAS, sensor, network, or production automation has recovered.&lt;/p&gt;

&lt;h2&gt;
  
  
  The client behind the announcement
&lt;/h2&gt;

&lt;p&gt;MQTT is a publish/subscribe protocol. A publisher sends a message to a topic, and the broker delivers it to clients with matching subscriptions. The protocol defines how messages are routed. It doesn't define what a payload such as &lt;code&gt;online&lt;/code&gt;, &lt;code&gt;ready&lt;/code&gt;, or &lt;code&gt;homeassistant&lt;/code&gt; means for a particular product. Topic names and payload values are configuration, not universal diagnostics. &lt;a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html" rel="noopener noreferrer"&gt;The MQTT 5.0 specification&lt;/a&gt; is the reference for topics, subscriptions, retained messages, sessions, and connections.&lt;/p&gt;

&lt;p&gt;The Home Assistant MQTT integration has settings for a birth message and a last-will message. That birth message belongs to the Home Assistant MQTT client. Its publication tells you about that client's connection and configured message. It doesn't tell you whether every other MQTT client received it, acted on it, or has valid data. &lt;a href="https://www.home-assistant.io/integrations/mqtt/" rel="noopener noreferrer"&gt;Home Assistant's MQTT integration documentation&lt;/a&gt; describes these settings and how they relate to broker connectivity.&lt;/p&gt;

&lt;p&gt;Be clear about which client each observation concerns. A message on &lt;code&gt;homeassistant/status&lt;/code&gt; may describe Home Assistant, while a device-specific availability topic may describe a particular publisher according to that device's configuration. A broker log may show a connection. These facts can support each other, but none can stand in for the others.&lt;/p&gt;

&lt;h2&gt;
  
  
  One reversible test path
&lt;/h2&gt;

&lt;p&gt;Use a broker and Home Assistant instance that you administer. Pick a new lab topic, such as &lt;code&gt;lab/reconnect-check-2026-10-27&lt;/code&gt;, rather than a topic that controls a real device. Keep credentials, private addresses, commands, and personal identifiers out of it.&lt;/p&gt;

&lt;p&gt;Before restarting anything, write down the exact details of the test:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The Home Assistant birth topic and payload as configured in the MQTT integration.&lt;/li&gt;
&lt;li&gt;The lab topic and payload a known test publisher will use after it reconnects.&lt;/li&gt;
&lt;li&gt;Whether each message is retained.&lt;/li&gt;
&lt;li&gt;The entity or helper that will record the observation.&lt;/li&gt;
&lt;li&gt;The expected order of events and the clock you will use for comparison.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This record helps you avoid a common mistake: recognizing a value but attributing it to the wrong source. The broker can deliver a retained message to a new subscriber because it has stored that message. That's useful for state, but it doesn't necessarily mean someone published a new message after the restart. Change retain settings only in the lab path, and clean them up when you're done.&lt;/p&gt;

&lt;h2&gt;
  
  
  Separate observations of Home Assistant and the publisher
&lt;/h2&gt;

&lt;p&gt;First, check that Home Assistant connects to the broker and publishes its configured birth message. Use the broker's own log or subscribe to the exact configured topic. Record the time, topic, payload, and received retain flag, and record the publisher's retain configuration separately. The dashboard alone isn't enough to establish the result.&lt;/p&gt;

&lt;p&gt;Next, reconnect one known lab publisher and have it publish a distinct test payload to the lab topic. Observe that message independently. If the publisher sends a device-discovery configuration, check that Home Assistant has created the intended entity before using its state as a reconnect signal. Home Assistant documents MQTT discovery separately from the underlying broker connection. &lt;a href="https://www.home-assistant.io/integrations/mqtt/#mqtt-discovery" rel="noopener noreferrer"&gt;Its discovery documentation&lt;/a&gt; makes the distinction between configuration publication and state publication: they're separate events.&lt;/p&gt;

&lt;p&gt;If either observation is missing, compare spelling, case, topic hierarchy, authentication, and retain behavior before restarting more services. A broad restart can obscure the order of events that would have explained the problem. Change one variable. Then repeat the small test.&lt;/p&gt;

&lt;h2&gt;
  
  
  An automation for recording the event
&lt;/h2&gt;

&lt;p&gt;Once both test messages appear in the expected order, add a temporary automation to record the lab publisher's reconnect. A state trigger observes an entity's state transition; an MQTT trigger observes a message on a configured topic. Choose based on the fact you want to observe, even if you're more familiar with the other trigger. &lt;a href="https://www.home-assistant.io/docs/automation/trigger/" rel="noopener noreferrer"&gt;Home Assistant's automation trigger reference&lt;/a&gt; explains both trigger families.&lt;/p&gt;

&lt;p&gt;For the first run, make the action a persistent notification, logbook entry, or helper value. Don't restart services, switch power, publish to a command topic, or change network configuration. Reconnect the lab publisher once, then inspect the automation trace. Home Assistant's &lt;a href="https://www.home-assistant.io/docs/automation/troubleshooting/" rel="noopener noreferrer"&gt;automation troubleshooting guide&lt;/a&gt; distinguishes between a trigger that didn't fire and a condition or action that didn't complete.&lt;/p&gt;

&lt;p&gt;The trace confirms only the configured rule's path. It doesn't prove that a real device finished its own recovery. If a notification appears twice, investigate before adding a delay or retry. There might have been two connections, a retained message, duplicate automations, or a repeat from the publisher.&lt;/p&gt;

&lt;h2&gt;
  
  
  Availability and the reconnect marker
&lt;/h2&gt;

&lt;p&gt;An MQTT entity can expose an availability state based on a configured availability topic. It's often useful to compare that state with a reconnect marker, but they answer different questions. A client can reconnect while a device still reports unavailable. A retained offline state can remain until a publisher replaces it. The &lt;a href="https://www.home-assistant.io/integrations/sensor.mqtt/" rel="noopener noreferrer"&gt;MQTT sensor documentation&lt;/a&gt; describes state and availability as distinct configuration paths.&lt;/p&gt;

&lt;p&gt;Put the observations in a short table in your notes instead of trying to combine them in your head: Home Assistant birth observed, lab publisher message observed, entity availability, and automation trace. Include a time and source for each entry. Record what you observed, without assigning a cause. An example entry, if supported by your observations, is ‘Publisher reconnect observed at 10:03.’ “The device is healthy” may not be.&lt;/p&gt;

&lt;p&gt;DeviceShelf Server can expose network observations to a Home Assistant installation you administer through MQTT discovery. That gives you an additional observation to compare with broker and service records. It doesn't establish why a client reconnected, guarantee a device's availability, or confirm that an automation action succeeded. Keep that observation separate from the restart marker.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test cleanup and the next check
&lt;/h2&gt;

&lt;p&gt;When you're finished, disable or remove the temporary automation and lab topic configuration. Clear any retained test data you created, and verify that no test message can trigger a real action. Keep the topic names, payloads, timestamps, broker observation, and trace result, but don't retain any secrets.&lt;/p&gt;

&lt;p&gt;A useful result is narrow: Home Assistant published its configured birth message, one known lab publisher reconnected and published its test message, and one harmless automation recorded that event. If a part is missing, investigate that part first. Get the lab path repeatable before deciding whether a production automation needs a separate recovery check.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources checked
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.home-assistant.io/integrations/mqtt/" rel="noopener noreferrer"&gt;Home Assistant MQTT integration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.home-assistant.io/integrations/mqtt/#mqtt-discovery" rel="noopener noreferrer"&gt;Home Assistant MQTT discovery&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.home-assistant.io/integrations/sensor.mqtt/" rel="noopener noreferrer"&gt;Home Assistant MQTT sensor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.home-assistant.io/docs/automation/trigger/" rel="noopener noreferrer"&gt;Home Assistant automation triggers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.home-assistant.io/docs/automation/troubleshooting/" rel="noopener noreferrer"&gt;Home Assistant automation troubleshooting&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html" rel="noopener noreferrer"&gt;OASIS MQTT Version 5.0 specification&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://deviceshelf.app/server" rel="noopener noreferrer"&gt;Server documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>tutorial</category>
      <category>networking</category>
      <category>homelab</category>
      <category>selfhosted</category>
    </item>
    <item>
      <title>Home Assistant MQTT Discovery: Verify an Entity Before an Automation</title>
      <dc:creator>DeviceShelf</dc:creator>
      <pubDate>Mon, 26 Oct 2026 10:00:07 +0000</pubDate>
      <link>https://dev.to/deviceshelf/home-assistant-mqtt-discovery-verify-an-entity-before-an-automation-366</link>
      <guid>https://dev.to/deviceshelf/home-assistant-mqtt-discovery-verify-an-entity-before-an-automation-366</guid>
      <description>&lt;p&gt;MQTT discovery can make a Home Assistant entity appear quickly. That's useful, but seeing an entity card is just the first check. On its own, it doesn't prove that the publisher is still connected, that the value is fresh, or that an automation should act on it.&lt;/p&gt;

&lt;p&gt;This guide covers a narrow test on an MQTT broker and Home Assistant installation you administer. The goal is simple: confirm that a known test message creates or updates the intended entity and that a harmless automation can observe the update. The test doesn't certify a device, establish its availability, or prove that a real-world action completed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Discovery and current state
&lt;/h2&gt;

&lt;p&gt;Home Assistant's MQTT discovery mechanism lets a publisher describe entities through MQTT configuration topics. &lt;a href="https://www.home-assistant.io/integrations/mqtt/#mqtt-discovery" rel="noopener noreferrer"&gt;Home Assistant: MQTT discovery&lt;/a&gt; The configuration can include a state topic, an availability topic, and identifiers that group entities into a device. Those fields describe parts of the integration. They don't check the source's health.&lt;/p&gt;

&lt;p&gt;An entity might exist because Home Assistant received a retained discovery configuration earlier. The displayed value could be an old retained state. Or the entity could be unavailable because its publisher disconnected. Check each part separately: did discovery create the expected entity, did a state message update it, and did an automation receive the intended state transition?&lt;/p&gt;

&lt;p&gt;Write down the exact discovery topic, state topic, entity ID, expected test value, and test time. Exact names matter here. A broker doesn't interpret MQTT topics by intent; the protocol defines how strings and filters match. &lt;a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html" rel="noopener noreferrer"&gt;OASIS MQTT Version 5.0&lt;/a&gt; A discovery topic for one test device and a state topic for another may both look right while referring to different paths.&lt;/p&gt;

&lt;h2&gt;
  
  
  A dedicated lab entity
&lt;/h2&gt;

&lt;p&gt;Don't start by changing a discovered entity that controls power, networking, backups, or access. Create or choose a clearly labeled lab entity on a broker you control. Give its topic a purpose and a date, such as &lt;code&gt;lab/discovery-check-2026-10-24/state&lt;/code&gt;. Keep credentials, addresses, and realistic commands out of the payload.&lt;/p&gt;

&lt;p&gt;If you publish the discovery configuration yourself, use a supported component such as &lt;code&gt;sensor&lt;/code&gt; and an unused discovery topic/object ID so it can't replace a real entity. If you supply a &lt;code&gt;unique_id&lt;/code&gt; in the payload, it must also be distinct from those of existing entities. Record whether the configuration is retained. Retention can make sense for discovery data, but it's also why an entity can stay visible after the publisher stops. Stopping a test client doesn't remove a retained configuration. Plan that cleanup before you test.&lt;/p&gt;

&lt;p&gt;For the lab sensor to appear under a device, supply a distinct &lt;code&gt;unique_id&lt;/code&gt; and valid &lt;code&gt;device&lt;/code&gt; information containing &lt;code&gt;identifiers&lt;/code&gt; or &lt;code&gt;connections&lt;/code&gt;. You can inspect the device and entity views, but the UI doesn't verify the publisher's descriptive fields. &lt;a href="https://www.home-assistant.io/integrations/mqtt/#mqtt-discovery" rel="noopener noreferrer"&gt;Home Assistant: MQTT discovery&lt;/a&gt; Use factual names for the lab check. “MQTT discovery lab entity” tells you more than a name suggesting that a particular NAS, sensor, or service has been confirmed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Entity verification with a known state change
&lt;/h2&gt;

&lt;p&gt;Let Home Assistant receive the discovery configuration, then find the entity in its MQTT integration or developer tools. Note its entity ID. Don't assume the friendly name determines it. Publish one harmless, unambiguous state value through the declared state topic, such as &lt;code&gt;check-1&lt;/code&gt; if the entity configuration accepts text.&lt;/p&gt;

&lt;p&gt;Watch the entity state and record the time. If it updates correctly, you've shown that this message matched this configured path in this installation. That doesn't demonstrate delivery during a future broker restart, packet loss, or a different subscriber session. If nothing changes, compare the configured state topic with the published topic character by character before changing broader broker settings.&lt;/p&gt;

&lt;p&gt;Repeat the check with a deliberately different value, such as &lt;code&gt;check-2&lt;/code&gt;. Two distinct values tell you more than sending the same value repeatedly because they help distinguish a current update from an already retained display. If the entity uses a numeric or JSON value template, send a payload that's valid for that template. Don't weaken the configuration just to pass the test.&lt;/p&gt;

&lt;h2&gt;
  
  
  An automation for observation
&lt;/h2&gt;

&lt;p&gt;Once you've seen the state change, create a temporary automation that watches only the lab entity. A Home Assistant state trigger can match a specific state transition. The documentation also explains how an entity state differs from an attribute. &lt;a href="https://www.home-assistant.io/docs/automation/trigger/#state-trigger" rel="noopener noreferrer"&gt;Home Assistant: state trigger&lt;/a&gt; Use the entity's actual state, not a guessed attribute.&lt;/p&gt;

&lt;p&gt;Keep the first action reversible. Write a logbook entry, create a persistent notification, or set a dedicated test helper. Don't start a service, reboot a host, or publish to a command topic for this initial test. Trigger the test value once, then inspect the automation trace and its harmless result. If the entity updates but there's no trace, look at the automation configuration. If there's a trace but the expected action is missing, look at the conditions or action sequence.&lt;/p&gt;

&lt;p&gt;A short test sequence is enough:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Record the discovery topic, state topic, entity ID, and expected test value.&lt;/li&gt;
&lt;li&gt;Publish or confirm the lab discovery configuration, then find the resulting entity.&lt;/li&gt;
&lt;li&gt;Send &lt;code&gt;check-1&lt;/code&gt; on the exact state topic and record the entity state and time.&lt;/li&gt;
&lt;li&gt;Send &lt;code&gt;check-2&lt;/code&gt;, then confirm that the state changed again.&lt;/li&gt;
&lt;li&gt;Create and enable a temporary automation with a state trigger for the lab entity's transition from &lt;code&gt;check-1&lt;/code&gt; to &lt;code&gt;check-2&lt;/code&gt; and a notification or log entry as its only action. Publish &lt;code&gt;check-1&lt;/code&gt; followed by &lt;code&gt;check-2&lt;/code&gt; again on the exact state topic, then verify that the resulting automation trace identifies the expected state trigger and that the notification or log entry exists.&lt;/li&gt;
&lt;li&gt;Disable or remove the automation and clean up the lab discovery configuration when the check is complete.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  A separate availability check
&lt;/h2&gt;

&lt;p&gt;An entity update doesn't tell you the same thing as availability. MQTT discovery supports availability configuration, but receiving a state once doesn't prove the publisher is still online. An unavailable state doesn't tell you the cause, either. The problem could be a broker connection, an availability topic, a configuration mismatch, or the publisher itself.&lt;/p&gt;

&lt;p&gt;If an automation depends on availability, make sure it behaves safely when availability is absent. For a workflow with real consequences, start with a notification containing the observed entity state and time. Review that record before adding a real action. Keep “Home Assistant received a test state” separate from “the device is ready for an operation.”&lt;/p&gt;

&lt;p&gt;DeviceShelf Server can export network observations through MQTT discovery for a Home Assistant setup you administer. It can provide entities and events to inspect alongside broker records. But that doesn't prove a discovered entity is current, a device identity is certain, or an automation completed. Check each of those on the specific path you use.&lt;/p&gt;

&lt;p&gt;The result is intentionally limited: one controlled publisher produced two distinguishable test states, Home Assistant displayed them on the intended entity, and a temporary automation recorded one reversible observation. That's enough evidence to continue carefully. It isn't a reason to widen subscriptions or trust an untested action.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources checked
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.home-assistant.io/integrations/mqtt/#mqtt-discovery" rel="noopener noreferrer"&gt;Home Assistant MQTT discovery&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.home-assistant.io/docs/automation/troubleshooting/" rel="noopener noreferrer"&gt;Home Assistant: troubleshooting automations (traces)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.home-assistant.io/docs/automation/trigger/#state-trigger" rel="noopener noreferrer"&gt;Home Assistant state trigger&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html" rel="noopener noreferrer"&gt;OASIS MQTT Version 5.0 specification&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://deviceshelf.app/server" rel="noopener noreferrer"&gt;DeviceShelf Server documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>tutorial</category>
      <category>networking</category>
      <category>homelab</category>
      <category>selfhosted</category>
    </item>
    <item>
      <title>MQTT Topic Mismatch in Home Assistant: A Safe Way to Find It</title>
      <dc:creator>DeviceShelf</dc:creator>
      <pubDate>Sat, 24 Oct 2026 09:00:06 +0000</pubDate>
      <link>https://dev.to/deviceshelf/mqtt-topic-mismatch-in-home-assistant-a-safe-way-to-find-it-4po0</link>
      <guid>https://dev.to/deviceshelf/mqtt-topic-mismatch-in-home-assistant-a-safe-way-to-find-it-4po0</guid>
      <description>&lt;p&gt;An MQTT publisher can connect to a broker and still leave a Home Assistant automation silent. Often, the network isn't the problem. The publisher sent to one topic while the subscriber listened to another, or a payload filter rejected a message that looked right at first glance.&lt;/p&gt;

&lt;p&gt;This guide assumes you administer the broker, Home Assistant instance, and test topic. It walks through a small test to isolate a topic mismatch before you change a real sensor, a NAS, or an automation whose actions have consequences. A successful test tells you what happened on that path. It doesn't prove that a device is healthy, that a network is secure, or that another automation will behave the same way.&lt;/p&gt;

&lt;h2&gt;
  
  
  The exact path before any edits
&lt;/h2&gt;

&lt;p&gt;Start by writing down four literal values: the broker, the topic the source publishes to, the topic configured in Home Assistant, and the payload the automation expects. Copy the topic strings. Don't rely on memory. MQTT topic names are case-sensitive, and a misplaced slash, space, or topic level means a different destination.&lt;/p&gt;

&lt;p&gt;Give each topic a narrowly defined meaning. &lt;code&gt;lab/nas/availability&lt;/code&gt; and &lt;code&gt;lab/nas/status&lt;/code&gt; might sound interchangeable, but they're different topics. A topic that reports a service state shouldn't quietly become a command topic, either. Keeping events, states, and commands separate lets you test one meaning at a time.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html" rel="noopener noreferrer"&gt;OASIS MQTT Version 5.0 specification&lt;/a&gt; defines topics and subscriptions as protocol concepts, but it doesn't give topic names universal meanings. Those come from the publisher and subscriber configuration in your installation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Home Assistant's actual subscription
&lt;/h2&gt;

&lt;p&gt;Home Assistant's MQTT integration lets you listen to a topic while testing your setup. &lt;a href="https://www.home-assistant.io/integrations/mqtt/" rel="noopener noreferrer"&gt;Home Assistant: MQTT&lt;/a&gt; Start with the exact topic. A temporary wildcard can help you find a message during a controlled lab test, but use it for diagnosis. It isn't a reason to leave an automation subscribed broadly.&lt;/p&gt;

&lt;p&gt;Record the topic, payload, and time of the message you receive. If the expected test message doesn't appear, compare the recorded publisher topic with the configured listener topic, character by character. Then check the broker address and port. Changing connection settings won't fix a difference between two topic strings.&lt;/p&gt;

&lt;p&gt;If the listener receives the message but the automation stays quiet, check the trigger configuration next. Home Assistant documents MQTT triggers separately from the integration itself. &lt;a href="https://www.home-assistant.io/docs/automation/trigger/#mqtt-trigger" rel="noopener noreferrer"&gt;Home Assistant: MQTT trigger&lt;/a&gt; The topic can match while a payload or template condition excludes the message. Delivery to the listener is confirmed, but that doesn't establish why the automation produced no result. Check the automation's enabled state, trigger, conditions, execution mode, and trace.&lt;/p&gt;

&lt;h2&gt;
  
  
  A dedicated test topic and harmless payload
&lt;/h2&gt;

&lt;p&gt;Don't test by publishing to a topic that operates equipment. Create a short-lived topic with a name that clearly marks it as a lab value, such as &lt;code&gt;lab/mqtt-topic-check-2026-10-22&lt;/code&gt;. Use a payload such as &lt;code&gt;test-arrived&lt;/code&gt;. Don't use a password, inventory, address, or realistic command. If several people administer the broker, document the topic before using it.&lt;/p&gt;

&lt;p&gt;Set up a temporary MQTT trigger for that exact test topic. Make its first action reversible: a persistent notification, a logbook entry, or an update to a dedicated test helper. Home Assistant conditions control whether an automation continues after a trigger. &lt;a href="https://www.home-assistant.io/docs/automation/condition/" rel="noopener noreferrer"&gt;Home Assistant: automation conditions&lt;/a&gt; Keep the condition simple enough that you can explain it from the captured payload.&lt;/p&gt;

&lt;p&gt;This sequence is enough to separate common mistakes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Listen for the exact lab topic in Home Assistant and note the start time.&lt;/li&gt;
&lt;li&gt;Publish one clearly marked test payload from a client you control.&lt;/li&gt;
&lt;li&gt;Check whether the listener received the same topic and payload.&lt;/li&gt;
&lt;li&gt;Check whether the message published in step 2 triggered the temporary automation, using its trace and harmless action.&lt;/li&gt;
&lt;li&gt;Publish a deliberately different payload that the condition should reject, then confirm that no action occurred.&lt;/li&gt;
&lt;li&gt;Remove or disable the temporary automation and stop using the lab topic when the check is complete.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This doesn't test all retained messages, broker restarts, or delivery guarantees. Those need separate checks. It tells you only whether the named topic and rule match the message you deliberately sent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Topic mismatches and payload mismatches
&lt;/h2&gt;

&lt;p&gt;If the listener receives nothing, look first at the publishing topic, broker connection, or subscription. If it receives the expected message but the automation stays inactive, the more likely causes are the automation's trigger, payload condition, mode, or disabled state. Keep that distinction in your notes. Don't change every setting at once.&lt;/p&gt;

&lt;p&gt;Compare payloads as carefully as topics. A filter expecting &lt;code&gt;online&lt;/code&gt; doesn't match &lt;code&gt;Online&lt;/code&gt;. Comparing the entire payload as text differs from extracting and comparing a field from parsed JSON, and even a hidden newline can matter in a simple comparison. Don't widen a filter just to make the test fire. Capture a non-sensitive test payload, write down the expected format, and adjust only the part that differs.&lt;/p&gt;

&lt;p&gt;Retained messages can confuse the picture, too. After connecting, a subscriber can receive the broker's retained value even though the source hasn't published a fresh event at that moment. Home Assistant documents the behavior of availability settings separately. &lt;a href="https://www.home-assistant.io/integrations/mqtt/#availability" rel="noopener noreferrer"&gt;Home Assistant: MQTT availability&lt;/a&gt; A retained state can be useful as last-known information. It doesn't establish that a NAS, sensor, or service is currently available.&lt;/p&gt;

&lt;h2&gt;
  
  
  Careful application to the real automation
&lt;/h2&gt;

&lt;p&gt;Once you understand the lab path, compare it with the real automation one field at a time: topic, payload expectation, condition, and action. Don't copy a wildcard or test-only payload into a production rule. If an action changes power, security, backups, or network configuration, start with a notification or log entry. Review the result before allowing the action with consequences to run.&lt;/p&gt;

&lt;p&gt;Keep a short record of the evidence: the test topic, payload format, time, what the listener received, and what the automation did. A later administrator can use that record to tell an actual message-format change apart from a broker outage or a disabled rule. It also helps prevent a lack of evidence from becoming a claim that a device has failed.&lt;/p&gt;

&lt;p&gt;DeviceShelf Server can publish network observations through MQTT for a network you administer. Those observations can be one input to compare with broker and automation records. They don't prove that a topic was delivered, that a device is identified with certainty, or that an automation completed. Check each observation independently.&lt;/p&gt;

&lt;p&gt;The result is limited, but you can test it: one deliberately sent message matched one intentionally configured topic and caused one reversible action. That gives you a sound starting point for diagnosing the next mismatch before touching a real device.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources checked
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html" rel="noopener noreferrer"&gt;OASIS MQTT Version 5.0 specification&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.home-assistant.io/integrations/mqtt/" rel="noopener noreferrer"&gt;Home Assistant MQTT integration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.home-assistant.io/docs/automation/trigger/#mqtt-trigger" rel="noopener noreferrer"&gt;Home Assistant MQTT trigger&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.home-assistant.io/docs/automation/condition/" rel="noopener noreferrer"&gt;Home Assistant automation conditions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.home-assistant.io/integrations/mqtt/#availability" rel="noopener noreferrer"&gt;Home Assistant MQTT availability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://deviceshelf.app/server" rel="noopener noreferrer"&gt;DeviceShelf Server documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>tutorial</category>
      <category>networking</category>
      <category>homelab</category>
      <category>selfhosted</category>
    </item>
    <item>
      <title>MQTT QoS in Home Assistant: Choose Delivery Expectations Before an Automation</title>
      <dc:creator>DeviceShelf</dc:creator>
      <pubDate>Thu, 22 Oct 2026 09:00:07 +0000</pubDate>
      <link>https://dev.to/deviceshelf/mqtt-qos-in-home-assistant-choose-delivery-expectations-before-an-automation-443c</link>
      <guid>https://dev.to/deviceshelf/mqtt-qos-in-home-assistant-choose-delivery-expectations-before-an-automation-443c</guid>
      <description>&lt;p&gt;An MQTT automation often starts with a reasonable idea: a device publishes an event, and Home Assistant reacts. The harder question is what that event needs to mean. Would a missed update just leave a dashboard a little untidy? Could a repeated event send two notifications? Would the action affect a lock, a heater, or another device that calls for a more conservative design?&lt;/p&gt;

&lt;p&gt;Quality of Service, usually shortened to QoS, is part of that choice. It describes the delivery handshake requested between an MQTT client and a broker. It doesn't prove that a sensor measured correctly or that a device is reachable right now. Nor does it prove that Home Assistant completed an automation. Define the consequence first, then choose a QoS level. That gives you clearer tests than changing a number after an alert behaves oddly.&lt;/p&gt;

&lt;h2&gt;
  
  
  The event and its consequence
&lt;/h2&gt;

&lt;p&gt;Before changing a QoS setting, write down the exact topic, payload, publisher, and consumer. A temperature report can fail in different ways than a button press or an availability signal. The next reading can replace a periodic temperature report. A button press may matter once but cause trouble if it's handled as a command twice. An availability topic may describe an application's connection to the broker rather than the state of a service on the device.&lt;/p&gt;

&lt;p&gt;Home Assistant's MQTT integration lets entities and automations subscribe to MQTT topics. That doesn't make a message a complete health check. Check its documentation for configuration syntax and supported MQTT features. &lt;a href="https://www.home-assistant.io/integrations/mqtt/" rel="noopener noreferrer"&gt;Home Assistant: MQTT&lt;/a&gt; If an action depends on the actual service, you still need to test that service separately.&lt;/p&gt;

&lt;p&gt;Be precise about what you've established. “The broker accepted a publish at this QoS” is different from “the automation ran” and different again from “the physical device did what the payload described.” Keeping those distinctions clear makes an incident easier to investigate later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Delivery behavior at QoS 0, 1, and 2
&lt;/h2&gt;

&lt;p&gt;The MQTT specification defines three QoS levels for application messages. &lt;a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html" rel="noopener noreferrer"&gt;OASIS MQTT Version 5.0&lt;/a&gt; These describe delivery expectations between participating MQTT clients and the broker. They aren't a ranking of data quality.&lt;/p&gt;

&lt;p&gt;At QoS 0, the sender makes no acknowledgment-based retry request for the publication. This is commonly described as “at most once.” It can suit frequent observations that the next update can replace, such as a regularly updated measurement where a new value is more useful than an old one. Gaps can be harder to see, though. A missing message alone doesn't tell you which network or client step failed.&lt;/p&gt;

&lt;p&gt;At QoS 1, the receiver acknowledges the publication. This is commonly described as “at least once.” With MQTT 5, unacknowledged QoS 1 publications are retransmitted when a connection resumes an existing session. The receiver may therefore receive duplicates. If an automation treats each copy as a fresh command, it may send a duplicate notification or repeat an action. Design the payload and automation so that repeating the same event is safe, or record a sequence number or timestamp controlled by the publisher.&lt;/p&gt;

&lt;p&gt;QoS 2 uses a longer exchange intended to arrange “exactly once” delivery within the MQTT protocol flow. That isn't a general promise about what happens outside that flow. It doesn't mean the real-world event happened once or that a downstream HTTP call ran once. An automation could still be triggered again after a restart or by a different message. QoS 2 adds protocol work, so use it only after showing why the application needs that delivery behavior.&lt;/p&gt;

&lt;h2&gt;
  
  
  Subscription QoS
&lt;/h2&gt;

&lt;p&gt;Publishing and subscribing are separate choices. When a client subscribes, it requests a maximum QoS for messages delivered on that subscription. The broker uses the applicable level for delivery. Setting a high value in one part of the path doesn't upgrade every message along it. The specification describes this negotiation; your broker's documentation or logs can show what your deployment actually accepted.&lt;/p&gt;

&lt;p&gt;The Mosquitto command-line clients let you publish and subscribe with a selected QoS for a small, controlled check. Their options are documented in the &lt;a href="https://mosquitto.org/man/mosquitto_pub-1.html" rel="noopener noreferrer"&gt;mosquitto_pub manual&lt;/a&gt; and &lt;a href="https://mosquitto.org/man/mosquitto_sub-1.html" rel="noopener noreferrer"&gt;mosquitto_sub manual&lt;/a&gt;. Keep the test topic separate from real device commands, and never include passwords, addresses, or personal data in the test payload.&lt;/p&gt;

&lt;p&gt;Use this sequence to keep the test reversible:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a uniquely named lab topic on a broker and network you administer, such as &lt;code&gt;lab/qos-check-2026-10-21&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Start a subscriber that displays the selected QoS and note its connection time. Record its client ID, subscription QoS, clean-session/clean-start setting, and session expiry.&lt;/li&gt;
&lt;li&gt;Publish an unmistakable test payload with QoS 0, then repeat with QoS 1. Do not publish to a command topic.&lt;/li&gt;
&lt;li&gt;Disconnect only the lab subscriber at a controlled point, reconnect it, and record what arrived. Testing delivery across a disconnect requires a persistent session resumed with the same client ID; QoS alone does not preserve a subscription. Don't use this result to infer how unrelated devices behave.&lt;/li&gt;
&lt;li&gt;If you're testing an automation, make its first action a reversible logbook entry or persistent notification. Check the automation trace separately from the broker output.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Add QoS 2 to the same lab exercise only if you have a stated reason to compare it. A successful client connection proves only that the client can connect. It doesn't establish that a production sensor or automation has the same settings.&lt;/p&gt;

&lt;h2&gt;
  
  
  Duplicate messages and repeated side effects
&lt;/h2&gt;

&lt;p&gt;If an automation has a side effect, plan for retries or duplicates before relying on QoS 1. An event ID in the payload gives the consumer something concrete to compare. A monotonic counter or timestamp can do the same, but use only a field that the publisher actually controls and documents. A time displayed by another system may not be comparable if clocks are wrong or formats differ.&lt;/p&gt;

&lt;p&gt;Choose an action that's safe to repeat, or add a deliberate check before it runs. A notification, for example, can include the event ID. A command that changes a device should first compare the desired state with the current authorized observation. A short, logged cooldown may help with an alert. Make that an explicit policy decision, though, rather than a hidden way to dismiss duplicates you haven't explained.&lt;/p&gt;

&lt;p&gt;Check retained messages separately. A client can receive a retained state message when it subscribes later; that doesn't necessarily mean an active device has just published it. Test retained state, availability, and event topics separately. Don't reuse an event topic as a retained state topic unless the publisher's design explicitly supports it.&lt;/p&gt;

&lt;h2&gt;
  
  
  QoS in a wider diagnosis
&lt;/h2&gt;

&lt;p&gt;If a message seems to be missing, inspect the smallest relevant chain: publisher connection, broker log, topic spelling, subscription, Home Assistant configuration, and automation trace. If it appears twice, save the topic and payload along with the QoS, time, and client logs before changing settings. That record can help distinguish a publisher retry from two independent publications or two subscriptions.&lt;/p&gt;

&lt;p&gt;An inventory or network-observation tool can give you another local clue about devices on a network you administer. DeviceShelf is one option for recording an observed address and time alongside MQTT evidence. It doesn't prove MQTT delivery, device identity, availability, or the success of an automation.&lt;/p&gt;

&lt;p&gt;QoS is most useful when you've matched it to a documented consequence. Choose QoS 0 when it's acceptable for newer data to supersede an earlier value. Make QoS 1 consumers tolerant of duplicates. Use QoS 2 only for a demonstrated protocol need, then test the entire path that matters. You still don't have a guarantee. You do have a precise, repeatable expectation for the next event.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources checked
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html" rel="noopener noreferrer"&gt;OASIS MQTT Version 5.0 specification&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.home-assistant.io/integrations/mqtt/" rel="noopener noreferrer"&gt;Home Assistant MQTT integration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mosquitto.org/man/mosquitto_pub-1.html" rel="noopener noreferrer"&gt;Mosquitto mosquitto_pub manual&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mosquitto.org/man/mosquitto_sub-1.html" rel="noopener noreferrer"&gt;Mosquitto mosquitto_sub manual&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://deviceshelf.app/server" rel="noopener noreferrer"&gt;DeviceShelf Server documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>tutorial</category>
      <category>networking</category>
      <category>homelab</category>
      <category>selfhosted</category>
    </item>
    <item>
      <title>MQTT Last Will Messages: What an Offline Alert Actually Means</title>
      <dc:creator>DeviceShelf</dc:creator>
      <pubDate>Tue, 20 Oct 2026 09:00:10 +0000</pubDate>
      <link>https://dev.to/deviceshelf/mqtt-last-will-messages-what-an-offline-alert-actually-means-pjo</link>
      <guid>https://dev.to/deviceshelf/mqtt-last-will-messages-what-an-offline-alert-actually-means-pjo</guid>
      <description>&lt;p&gt;An MQTT-based dashboard can mark a device offline within seconds of losing its connection. That's useful, especially when the device normally keeps a persistent connection to the broker. But it's easy to read too much into the alert. An offline MQTT message alone doesn't prove that a NAS lost power, a service stopped, or the whole network went down.&lt;/p&gt;

&lt;p&gt;These alerts often come from MQTT's Last Will and Testament feature, usually called LWT. It lets a client leave the broker a message to publish if the connection ends unexpectedly. This guide covers what that message tells you, how to test it without disrupting a working setup, and how to keep an automation's conclusions within what its input actually shows.&lt;/p&gt;

&lt;h2&gt;
  
  
  The connection event visible to the broker
&lt;/h2&gt;

&lt;p&gt;An MQTT client can supply a will message with a topic, payload, quality-of-service setting, and optional retained flag. If the broker detects that the connection ended without a normal disconnect, it can publish that message for the client. The broker is reporting what happened to a client connection. It isn't checking every process or network interface on the device.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html" rel="noopener noreferrer"&gt;MQTT Version 5.0 specification&lt;/a&gt; defines will messages and the conditions for publishing them. It also covers session and delay options that can affect when a subscriber receives a will. Those settings matter if you're using the alert to trigger a time-sensitive response.&lt;/p&gt;

&lt;p&gt;A publisher might, for example, connect with an &lt;code&gt;online&lt;/code&gt; birth message and an &lt;code&gt;offline&lt;/code&gt; will. If Wi-Fi drops, the device loses power, or a network path fails, the broker may eventually publish &lt;code&gt;offline&lt;/code&gt;. That's good evidence that the broker didn't receive the expected graceful disconnect from that client. It doesn't tell you which cause was responsible. Nor does it tell you the state of a file share, web interface, or storage volume on the same machine.&lt;/p&gt;

&lt;p&gt;Before turning a topic into an alert, write down exactly what it tells you. “MQTT client connection was lost” is a narrow claim you can test. “NAS is broken” rolls several separate questions into one and needs more evidence.&lt;/p&gt;

&lt;h2&gt;
  
  
  Graceful stops and unexpected connection loss
&lt;/h2&gt;

&lt;p&gt;An application can normally disconnect from a broker cleanly. Depending on the client configuration and protocol settings, that can prevent the broker from publishing a will. The will is meant to report an ungraceful connection loss; it isn't a general shutdown log. You can't reliably use it to tell whether someone deliberately stopped a service.&lt;/p&gt;

&lt;p&gt;Keepalive affects the timing, too. MQTT clients and brokers use it to detect a connection that has gone quiet. The broker won't necessarily detect the loss at the instant someone unplugs a cable. The delay depends on the configured interval, network timing, and broker behavior. Record when the subscriber received the message; record the broker's detection time separately only when supported by broker logs. Will Delay, delivery delays, and retained-message replay can separate those times.&lt;/p&gt;

&lt;p&gt;Home Assistant documents an MQTT integration with birth and last-will messages, along with availability topics for MQTT entities. Its &lt;a href="https://www.home-assistant.io/integrations/mqtt/#availability" rel="noopener noreferrer"&gt;availability documentation&lt;/a&gt; explains the distinction between an entity's current value and the connection signal used to decide whether that value is available.&lt;/p&gt;

&lt;p&gt;An &lt;code&gt;offline&lt;/code&gt; will can be retained. That may be useful when a new subscriber needs the last known availability state. There's a catch, though: a subscriber can receive a stored offline value when it starts. That message reports the last recorded state, which doesn't necessarily mean a new outage happened when the subscriber connected.&lt;/p&gt;

&lt;h2&gt;
  
  
  A controlled test topic
&lt;/h2&gt;

&lt;p&gt;Run tests only on a broker and network you administer. Pick a separate, clearly labeled test topic instead of a production device-control topic or a wildcard subscription. Don't reuse a topic that drives a lock, switch, alert escalation, or any other physical action.&lt;/p&gt;

&lt;p&gt;Set up a disposable client with an &lt;code&gt;online&lt;/code&gt; birth message and an &lt;code&gt;offline&lt;/code&gt; will. Use a second authorized client to subscribe, and record the topic, payload, subscriber receipt time, retained indicator, and configured keepalive. Stop the publisher normally first. Check whether the broker publishes the will. In a separate test, interrupt the client's network path or terminate its process abruptly so it cannot send DISCONNECT, then watch whether the subscriber receives the will and when it arrives.&lt;/p&gt;

&lt;p&gt;Mosquitto's &lt;a href="https://mosquitto.org/man/mosquitto_sub-1.html" rel="noopener noreferrer"&gt;subscriber manual&lt;/a&gt; documents a command-line client you can use to watch a test topic. Its output shows which messages it received. That doesn't prove every other subscriber reacted or that the device itself is unreachable through another route.&lt;/p&gt;

&lt;p&gt;Use clear test payloads that contain no sensitive information. A short value like &lt;code&gt;test-online&lt;/code&gt; or &lt;code&gt;test-offline&lt;/code&gt; is safer than a real hostname, private address, inventory data, token, or credential. If you use a retained will for the test, clear the retained test value after recording the result. That's good housekeeping, but it won't undo any copies a subscriber has already processed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Independent checks for the question at hand
&lt;/h2&gt;

&lt;p&gt;Choose an independent check based on what you would do with the result. To find out whether a NAS file service is reachable, test the documented service through an authorized path. To check whether the host rebooted, compare an uptime record or system log. For a possible Wi-Fi change, look at the network equipment's current association information. Each answers a different question from an MQTT connection event.&lt;/p&gt;

&lt;p&gt;You can also have an automation wait through a short, documented grace period before sending a notification. After the grace period, notify only if the offline condition still holds. This cuts down on noise from brief Wi-Fi changes or broker restarts. It doesn't make LWT a health check. One useful condition might require both an offline will and no fresh publisher timestamp after the expected interval. Test the rule with an intentionally short interruption and an ordinary graceful stop, as well as a broker or subscriber restart.&lt;/p&gt;

&lt;p&gt;Don't test by blocking unfamiliar devices or changing router settings on a live household network. A controlled test client gives you a clear result with less risk of disrupting an authorized user. If a production result surprises you, save the topic, time, payload, client identifier where appropriate, and broker logs before changing several settings at once.&lt;/p&gt;

&lt;h2&gt;
  
  
  Restart behavior and retained availability
&lt;/h2&gt;

&lt;p&gt;Broker and subscriber restarts are normal. They can briefly interrupt connections or cause retained availability messages to appear. Before attaching a notification to a topic, restart the subscriber during a test window and check whether it receives a previously retained state. Then, when it's safe and authorized, restart the broker and watch how the publishers reconnect.&lt;/p&gt;

&lt;p&gt;This matters for Home Assistant automations. A trigger that runs when Home Assistant reconnects can process a value that was already there before the restart. An arriving message needs to be evaluated; it doesn't automatically mean there's a new incident. If the publisher supports it, a timestamp, a monotonic counter, or a separately modeled availability state can make the rule more specific.&lt;/p&gt;

&lt;p&gt;DeviceShelf Server can publish network observations to a Home Assistant installation you administer. Treat it as one input among others. Compare an MQTT event with the observation time and the relevant device or service record; it doesn't guarantee device identity, availability, or security. The &lt;a href="https://deviceshelf.app/server" rel="noopener noreferrer"&gt;server documentation&lt;/a&gt; describes the supported integration path.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions supported by the evidence
&lt;/h2&gt;

&lt;p&gt;A reliable troubleshooting note after an alert can be short: “At this time, the subscriber received an offline message on the configured availability topic.” Record the independent check and its result separately. MQTT 5 also permits a client to deliberately request Will publication using DISCONNECT reason code &lt;code&gt;0x04&lt;/code&gt;, and retained delivery need not coincide with publication. This wording therefore establishes neither an unexpected disconnect nor the publication time.&lt;/p&gt;

&lt;p&gt;That's the practical value of LWT: it gives a managed system a standard way to communicate an unexpected MQTT disconnect. With a defined topic, a bounded test, and an independent follow-up observation, it can help you decide what to check next. On its own, a received offline message can indicate a broker connection problem, but may also reflect deliberate Will publication or a retained state. It doesn't establish the state of the whole device.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources checked
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html" rel="noopener noreferrer"&gt;OASIS: MQTT Version 5.0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.home-assistant.io/integrations/mqtt/" rel="noopener noreferrer"&gt;Home Assistant: MQTT integration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.home-assistant.io/integrations/mqtt/#availability" rel="noopener noreferrer"&gt;Home Assistant: MQTT availability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mosquitto.org/man/mosquitto_sub-1.html" rel="noopener noreferrer"&gt;Mosquitto: mosquitto_sub manual&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://deviceshelf.app/server" rel="noopener noreferrer"&gt;Server documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>tutorial</category>
      <category>networking</category>
      <category>homelab</category>
      <category>selfhosted</category>
    </item>
    <item>
      <title>How to Read a Stale Router Device Entry Before Calling It Unknown</title>
      <dc:creator>DeviceShelf</dc:creator>
      <pubDate>Sun, 18 Oct 2026 09:00:06 +0000</pubDate>
      <link>https://dev.to/deviceshelf/how-to-read-a-stale-router-device-entry-before-calling-it-unknown-338d</link>
      <guid>https://dev.to/deviceshelf/how-to-read-a-stale-router-device-entry-before-calling-it-unknown-338d</guid>
      <description>&lt;p&gt;An unfamiliar name, address, or old-looking entry in your router can be unsettling.&lt;br&gt;
But it doesn't tell you much on its own. Router interfaces often put several&lt;br&gt;
kinds of information on the same screen: devices connected to Wi-Fi now, DHCP&lt;br&gt;
leases issued earlier, remembered host names, and sometimes a history of&lt;br&gt;
clients. A row on that screen can be useful evidence. By itself, though, it&lt;br&gt;
doesn't show that a device is currently connected or belongs to an intruder.&lt;/p&gt;

&lt;p&gt;Start with a narrower question: what kind of record is this, and when was it&lt;br&gt;
last observed? Work that out before blocking an address, resetting the router,&lt;br&gt;
or changing a password. The steps below are for a network you own or are&lt;br&gt;
authorized to administer. The first checks are reversible, and each leaves you&lt;br&gt;
with a record of what you actually observed.&lt;/p&gt;

&lt;h2&gt;
  
  
  The type of router list
&lt;/h2&gt;

&lt;p&gt;Check the page label and its fields as well as the device name. A page called&lt;br&gt;
&lt;strong&gt;DHCP leases&lt;/strong&gt;, &lt;strong&gt;address reservations&lt;/strong&gt;, or &lt;strong&gt;known clients&lt;/strong&gt; can keep&lt;br&gt;
information after a client goes offline. DHCP is the protocol a server uses&lt;br&gt;
to assign an address for a lease time; RFC 2131 describes how clients obtain,&lt;br&gt;
renew, and release those leases. A lease tells you the server allocated an&lt;br&gt;
address. It doesn't necessarily mean there's a live Wi-Fi session.&lt;/p&gt;

&lt;p&gt;A current Wi-Fi association list tells you something different. It may show&lt;br&gt;
signal, band, connection time, or a short inactivity timer. An Ethernet switch’s MAC address table is another kind of observation. A router dashboard may combine all three&lt;br&gt;
without making the differences clear. Write down the page name beside the&lt;br&gt;
entry. When you compare it later, that detail helps you avoid treating a&lt;br&gt;
remembered lease as evidence of a current connection.&lt;/p&gt;

&lt;p&gt;Record the time, network name or VLAN, IP address, displayed hardware address,&lt;br&gt;
host name, and any last-seen or expiration value. Keep the note private:&lt;br&gt;
router screenshots can expose local addresses, Wi-Fi names, or administration&lt;br&gt;
details. No timestamp? Put that in the note too. Leave that uncertainty in the&lt;br&gt;
record instead of filling in a time from memory.&lt;/p&gt;

&lt;h2&gt;
  
  
  The lease lifetime
&lt;/h2&gt;

&lt;p&gt;A device can leave the room while its DHCP lease stays on the screen. A phone&lt;br&gt;
may be asleep, a laptop may have moved to another network, or a streaming box&lt;br&gt;
may simply be powered off. The router normally decides when to reuse an&lt;br&gt;
address based on how it handles leases. Manually deleting a row doesn't prove&lt;br&gt;
anything about who used it.&lt;/p&gt;

&lt;p&gt;Compare the entry's expiration or last-seen time with the time you recorded&lt;br&gt;
your observation. A recent Wi-Fi association and packets moving through the&lt;br&gt;
router are stronger evidence of current activity than an address under an old&lt;br&gt;
lease. A lease that expired long ago but still appears on the screen, on the&lt;br&gt;
other hand, may just be a remembered client. Router vendors use different&lt;br&gt;
words for these fields. Read the labels as that vendor's descriptions, not as&lt;br&gt;
status terms that mean the same thing on every router.&lt;/p&gt;

&lt;p&gt;Don't create an address conflict to test the record. RFC 5227 describes IPv4&lt;br&gt;
address-conflict detection used by hosts that implement it; deliberately&lt;br&gt;
assigning the same address can interrupt a printer, NAS, or another legitimate&lt;br&gt;
device. It's safer to observe what's there than to create a conflict.&lt;/p&gt;

&lt;h2&gt;
  
  
  The network boundary and a known device
&lt;/h2&gt;

&lt;p&gt;First, check which device is actually assigning addresses. Homes with a&lt;br&gt;
modem-router plus a separate Wi-Fi router, mesh system, guest network, or VLAN&lt;br&gt;
can have more than one client list. A device may belong on one list and be&lt;br&gt;
correctly absent from another. Note the SSID, subnet, and gateway of the&lt;br&gt;
network you're checking before comparing results from a scanner or a computer.&lt;/p&gt;

&lt;p&gt;Then test an ordinary explanation. Check household phones, tablets, printers,&lt;br&gt;
consoles, watches, and IoT devices on the same network. With the owner's&lt;br&gt;
permission, compare their Wi-Fi details, connection time, and displayed IP&lt;br&gt;
address with the router entry. Keep private Wi-Fi addresses in mind too.&lt;br&gt;
Apple documents private Wi-Fi addressing per network; a settings change,&lt;br&gt;
forgetting and rejoining a network, or a different privacy mode can make a&lt;br&gt;
familiar device appear under a different address. That doesn't prove the entry&lt;br&gt;
is harmless. It does give you a reason to compare before blocking it.&lt;/p&gt;

&lt;p&gt;Names and address prefixes are clues, not proof of identity. A host name can&lt;br&gt;
be generic, copied from an older record, or set by a user. A private or&lt;br&gt;
randomized address doesn't reliably identify a manufacturer. Write down what&lt;br&gt;
matches and what you're still unsure about, rather than guessing who owns a&lt;br&gt;
device from one label.&lt;/p&gt;

&lt;h2&gt;
  
  
  One limited, read-only observation
&lt;/h2&gt;

&lt;p&gt;If the entry is still unclear, make one observation from an authorized computer&lt;br&gt;
on the same network. Check the router's current association view, a managed&lt;br&gt;
switch table, or a local network scan that you understand. Record the method&lt;br&gt;
and time with the result. A device missing from a scan isn't a conclusive&lt;br&gt;
result: sleeping devices, firewalls, client isolation, and separate subnets can&lt;br&gt;
all affect what you can see.&lt;/p&gt;

&lt;p&gt;Avoid broad service probing or logging into an unfamiliar device. If you&lt;br&gt;
suspect a household printer or NAS, a less invasive way to check is to look at&lt;br&gt;
that known device's own network settings or watch its entry while its owner&lt;br&gt;
connects and disconnects it. DeviceShelf is one option for making another local&lt;br&gt;
observation on a network you administer, but it can't turn an ambiguous router&lt;br&gt;
record into a confirmed identity.&lt;/p&gt;

&lt;p&gt;You don't need a sweeping conclusion. “Old DHCP lease; no current association observed”&lt;br&gt;
is useful. So is “current connection observed; ownership not yet confirmed.”&lt;br&gt;
For the next review, a dated note of what you did and didn't see is better&lt;br&gt;
evidence than a confident label based on a single dashboard row.&lt;/p&gt;

&lt;h2&gt;
  
  
  Escalation based on the facts
&lt;/h2&gt;

&lt;p&gt;If a current connection is still unexplained after those comparisons, review&lt;br&gt;
who knows the Wi-Fi password, whether the guest network is separated, and&lt;br&gt;
whether the router firmware and administrator credentials are current. NIST's&lt;br&gt;
wireless LAN guidance provides a useful checklist for reviewing the network's&lt;br&gt;
security configuration. Make changes through the router vendor's documented&lt;br&gt;
interface, not through a link in a device name or a message about the device.&lt;/p&gt;

&lt;p&gt;Changing a Wi-Fi password can make sense when there's evidence behind a concern&lt;br&gt;
that an unauthorized person knows it. The change also disconnects legitimate&lt;br&gt;
devices, so plan for it and reconnect them deliberately. Blocking one MAC&lt;br&gt;
address isn't a complete security response: addresses can change, and a block&lt;br&gt;
doesn't replace secure Wi-Fi and router administration. If you've explained&lt;br&gt;
the record, keep a short inventory note. If you haven't, keep your observations&lt;br&gt;
and seek appropriate local administration help. Be clear about what the router&lt;br&gt;
list actually proved.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.rfc-editor.org/rfc/rfc2131.html" rel="noopener noreferrer"&gt;RFC 2131: Dynamic Host Configuration Protocol&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.rfc-editor.org/rfc/rfc5227.html" rel="noopener noreferrer"&gt;RFC 5227: IPv4 Address Conflict Detection&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.apple.com/en-us/102509" rel="noopener noreferrer"&gt;Apple Support: Use private Wi-Fi addresses&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://csrc.nist.gov/pubs/sp/800/153/final" rel="noopener noreferrer"&gt;NIST SP 800-153: Guidelines for Securing Wireless Local Area Networks&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>tutorial</category>
      <category>networking</category>
      <category>homelab</category>
      <category>selfhosted</category>
    </item>
  </channel>
</rss>
