New Integration: smart-sniffer - Proactive Disk Health Monitoring (No more "Manual" SMART Checks)

Hey RofoRo,

Saw your GitHub issue (#18), we’re tracking it there. :man_detective:

Your UPDATE 1 seems to confirm what we suspect: rebooting the VM woke the FireCuda, the agent’s next scan caught it awake, and it appeared. The fact that it disappeared again lines up with our theory that with standby_mode: standby, if the drive is asleep when the agent starts (or restarts), there’s a code path where it gets silently skipped on that first scan. It stays invisible until a future scan catches it awake, which with your 3-hour interval could take a while.

We’ve asked for some diagnostic output on the GitHub issue to confirm 100% before we fix it. If you can grab those when you get a chance, that would help us nail it down.

For anyone else reading this with a similar setup (standby mode + drives that sleep frequently) – we’re aware and working on it. Follow #18 on GitHub for updates.

~DAB

Hey @RofoRo – this is fixed. We confirmed the diagnosis and shipped the fix in v0.5.5.3 on your GitHub issue (#18).

For anyone else following this thread with a similar setup (standby mode + drives that sleep frequently): the agent now wakes all drives on its first poll after starting to collect a full SMART baseline. Sleeping drives no longer get silently dropped. From the second poll onward, standby mode works normally – sleeping drives are skipped and cached data is served.

Update to v0.5.5.3+ and restart the agent.

~DAB

1 Like

Hello!

Thanks for the integration.

Are you interested in adding the following?

IF the device is in the smart db:
Device is: In smartctl database 7.5/6131
then we can assume that the vendor specific smart IDs are all named properly.
I could use a couple of the IDs, so adding them named like ID_NAME and ID_NAME_RAW to the diagnostics part (disabled by default) would be helpful for me.
For example my device has a lot of vendor specific IDs, all named:

Vendor Specific SMART Attributes with Thresholds:
ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
  1 Raw_Read_Error_Rate     0x0000   100   100   000    Old_age   Offline      -       0
  5 Reallocated_Sector_Ct   0x0000   100   100   000    Old_age   Offline      -       0
  9 Power_On_Hours          0x0000   100   100   000    Old_age   Offline      -       3975
 12 Power_Cycle_Count       0x0000   100   100   000    Old_age   Offline      -       34
148 Total_SLC_Erase_Ct      0x0000   100   100   000    Old_age   Offline      -       98318
149 Max_SLC_Erase_Ct        0x0000   100   100   000    Old_age   Offline      -       1874
150 Min_SLC_Erase_Ct        0x0000   100   100   000    Old_age   Offline      -       1702
151 Average_SLC_Erase_Ct    0x0000   100   100   000    Old_age   Offline      -       1855
164 Total_Erase_Count       0x0000   100   100   000    Old_age   Offline      -       24237
165 Max_Erase_Count         0x0000   100   100   000    Old_age   Offline      -       35
166 Min_Erase_Count         0x0000   100   100   000    Old_age   Offline      -       4
167 Average_Erase_Count     0x0000   100   100   000    Old_age   Offline      -       26
159 DRAM_1_Bit_Error_Count  0x0000   100   100   000    Old_age   Offline      -       0
160 Uncorrectable_Error_Cnt 0x0000   100   100   000    Old_age   Offline      -       0
161 Valid_Spare_Block_Cnt   0x0000   100   100   000    Old_age   Offline      -       70
163 Initial_Bad_Block_Count 0x0000   100   100   000    Old_age   Offline      -       11
168 Max_Erase_Count_of_Spec 0x0000   100   100   000    Old_age   Offline      -       3000
169 Remaining_Lifetime_Perc 0x0000   100   100   000    Old_age   Offline      -       100
177 Wear_Leveling_Count     0x0000   100   100   050    Old_age   Offline      -       37
181 Program_Fail_Cnt_Total  0x0000   100   100   000    Old_age   Offline      -       0
182 Erase_Fail_Count_Total  0x0000   100   100   000    Old_age   Offline      -       0
192 Power-Off_Retract_Count 0x0000   100   100   000    Old_age   Offline      -       8
194 Temperature_Celsius     0x0000   100   100   000    Old_age   Offline      -       53
195 Hardware_ECC_Recovered  0x0000   100   100   000    Old_age   Offline      -       0
196 Reallocated_Event_Count 0x0000   100   100   016    Old_age   Offline      -       0
199 UDMA_CRC_Error_Count    0x0000   100   100   050    Old_age   Offline      -       0
232 Available_Reservd_Space 0x0000   100   100   000    Old_age   Offline      -       100
241 Host_Writes_32MiB       0x0000   100   100   000    Old_age   Offline      -       108650
242 Host_Reads_32MiB        0x0000   100   100   000    Old_age   Offline      -       19802
245 TLC_Writes_32MiB        0x0000   100   100   000    Old_age   Offline      -       96948

Obviously pulling names from smartctl would be a bad idea, if it doesn't know the underlying hardware.
Scrutiny can do something like this, but it can't get the names... and i want to get rid of it anyway :slight_smile:

Thanks!

1 Like

Hey devzor ~ good to hear from you again, and thanks for thinking through the database-gating logic. You're right on the mark.

When smartctl reports the drive is in its database, the attribute names in the JSON output are reliably mapped from drivedb.h. We can trust those names. When it's NOT in the database, the attribute IDs are vendor-specific and the names are either generic or wrong -- so your instinct to gate on database membership is exactly correct.

Good news: this is live now. Every named SMART attribute from the smartctl table that we don't already have a dedicated sensor for gets created as a diagnostic entity in HA. They're disabled by default ~ go to your drive's device page, scroll to the Diagnostic section, and enable whichever attributes you care about. Each one shows the raw value from the attribute table.

For your drive, you'd see things like Total SLC Erase Ct, Total Erase Count, Max Erase Count of Spec, Program Fail Cnt Total, Host Writes 32MiB, TLC Writes 32MiB, Available Reservd Space, and the rest ~ all as individual entities you can graph, automate against, or just keep an eye on.

We gate on exactly what you described: if the attribute name starts with "Unknown" (meaning the drive isn't in the database or that specific ID isn't mapped), we skip it. No junk entities.

What drive is that attribute table from, out of curiosity? The SLC/TLC erase count split and the attribute ID layout look like a Maxiotek or Silicon Motion controller-based SSD.

~DAB

1 Like

It's a silicon motion based Transcend MTS952T (i created the pull reqest for the drivedb... :sweat_smile:). Couple of years back i got a bunch of them, the 128gb version ("used", pulled from new notebooks) for a couple of euros . I use it as a workhorse in projects.

Quickly tested the new version, and i got 22 new sensors :+1:.
I still have this missing though:

169 Remaining_Lifetime_Perc 0x0000   100   100   000    Old_age   Offline      -       100

Is that intended ?

Thanks again!

1 Like

devzor ~ glad the new diagnostic entities are doing what they should on your end, and 22 sensors is a great signal. Thanks for the drive details too ~ knowing it's a Transcend MTS952T (Silicon Motion, your drivedb PR) makes this exchange much more useful than the average bug report.

On ID 169 (Remaining_Lifetime_Perc): not a bug, but not a clean answer either...

We have a consolidated wear_leveling_count sensor that swallows nine vendor name variants for "how much life is left": Wear_Leveling_Count (177), Remaining_Lifetime_Perc (169), Wear_Range_Delta, Media_Wearout_Indicator, SSD_Life_Left, Percent_Lifetime_Remain, Perc_Rated_Life_Remain, Percent_Life_Remaining, Drive_Life_Protection_Stat. The intent was to spare users from vendor-specific naming when the attributes all mean roughly the same thing.

The new diagnostic-entities feature then treats 169 as "already mapped" and skips it. On most drives only one of the nine variants is present and the consolidation is invisible. On your MTS952T, both 177 and 169 are reported, and only one wins the lookup. The other gets eaten.

Two ways to fix it ~ I'd value your opinion since you're closer to drivedb than most of our users:

  1. Split when multiple variants are present. Keep wear_leveling_count as the primary sensor for the common case. When a drive reports more than one of the nine variants, surface each as its own diagnostic entity. Your MTS952T would get both 177 and 169 as distinct entities.

  2. Keep consolidating, document better. Simpler, but loses information when drives report distinct values for what are technically distinct attributes.

My instinct is Option 1 ~ the whole point of the disabled-by-default diagnostics is power users seeing what the drive actually reports. Consolidation cuts against that. But you know the drivedb terrain better than I do; let me know which you'd prefer and I'll tag a follow-up.

~DAB

Why not both?
Pick and choose as you will.

1 Like

Thanks for detailed reply!

I think for diagnostics entries it should be option #1, just report them as-is and let the users decide what to do with it, it's disabled by default anyway. Consolidation should happen when you calculate the general health sensor / attention needed sensor status, so i don't think you need to change that, that's ok.
Consolidation documentation would be welcome for those sensors, but it's a "would be nice" low priority thing, if you have absolutely nothing else to work on.

Thanks again for your work!

1 Like

@devzor @IOT7712 -- agreed on all counts, and shipped in v0.5.14.

The diagnostic entity loop now only suppresses the single attribute variant that actually wins the consolidated sensor lookup. Any other variants from the same group surface as their own disabled-by-default diagnostic entities, just like every other uncovered attribute.

On your MTS952T, @devzor, you should now see Remaining Lifetime Perc (ID 169) as a new diagnostic entity alongside the existing Wear Leveling Count (ID 177) primary sensor. Same logic applies to the reported_uncorrectable_errors and current_pending_sector_count consolidation groups if a drive reports multiple variants there.

Update the integration via HACS and check your drive's device page ~ the new entities will hopefully appear disabled by default.

@devzor will do on the consolidation docs when we get a quiet stretch. Good call.

~DAB

Thanks for the update!

I have 1 more hidden diganostics sensors than before: 23 instead of 22 but Remaining Lifetime Perc (ID 169) is still missing somehow.

Hi there! I like the work of this integration, previously I had created a bunch of HA yaml sensors making ssh command calls to run smartctl on my other machines oover the network. Needless to say it’s a bit clunky. Installation of your integration and the smartha-agent went well and was easy :smiley:
I have a few diagnostic questions if this is the correct place for that or is there another place?

Thanks

Hey @Mad_Hat, welcome, and thanks for the kind words. Ask away here, or open an issue on GitHub if you’d like it tracked. If the two issues you opened (#49 and #56) are yours, I’ll keep answering there too.

~ DAB

Hey @devzor, I owe you an answer on this one, and I’m sorry it sat.

You got 23 diagnostic sensors instead of 22, but Remaining Lifetime Perc (ID 169) still isn’t showing for you.

Can you run smartctl -x --json /dev/<your drive> on the Transcend and paste the attribute table, or tell me whether ID 169 is in it?

Also worth updating first, since there have been several releases since v0.5.14. If 169 is in the output and missing in HA, that’s mine to fix.

~ DAB


From my Coding Assistant:

The diagnostic entities are built from the named attributes in smartctl’s table, and only when the drive is in smartctl’s database. Attribute 169 was also being folded into the consolidated wear_leveling_count sensor, and v0.5.14 stopped that for the diagnostic list. So the first thing to settle is whether 169 comes out of smartctl at all, and then whether the agent passes it along.