[RELEASE] Advanced Device Health Monitor – Auto-Healing, Custom Web Portal, & Complete Diagnostics!

Im working on a larger battery list, and custom battery options.

I'll have a new update out tomorrow, with this added. :+1:

1 Like

Hey everyone,

I’m happy to share the release of Version 1.5 of the Advanced Device Health Monitor.

Over the last few weeks, the main focus has been to keep our ecosystem of Advanced apps on the same page, bringing this health monitor up to the same standard of performance, automation, and usability as the rest of the lineup. We wanted to move beyond rigid global thresholds and static lists, offering a more dynamic and responsive way to manage your smart home infrastructure.

Here is a detailed breakdown of what is new and improved in v1.5:


:rocket: 1. High-Performance SPA Engine (Resolving Cloud Timeouts)

Generating a massive HTML document for 200+ devices occasionally caused 504 or 403 Gateway timeouts when accessed remotely via the Hubitat Cloud. To fix this, the architecture has been completely refactored.

  • Single Page Application (SPA): The web portal now uses asynchronous Client-Side Rendering (AJAX).
  • Instant Loading: Clicking your cloud link now instantly loads a lightweight UI shell, while your browser silently fetches the telemetry data in the background. It should now load smoothly over the cloud, regardless of your estate size.
  • Silent Auto-Refresh: The dashboard dynamically updates itself every 60 seconds without flashing or reloading the page.
  • Mobile Responsiveness: The UI has been heavily updated with flexbox and CSS media queries. Viewing the dashboard on your phone now drops the cards into a stacked grid, pins the navigation natively, and keeps all text easily readable without overlapping.

:brain: 2. EWMA Predictive Battery Math & Outdoor Profiles

Outdoor sensors often experience "Thermal Bounce"β€”where voltage drops at night due to the cold and bounces back up in the afternoon sun. Version 1.5 introduces a new way to calculate battery degradation to help smooth this out.

  • Exponentially Weighted Moving Average (EWMA): Instead of just looking at the raw percentage, the app now calculates a weighted rolling drop rate for every individual device. This filters out the bounce and provides a much more stable trendline.
  • Predictive Forecasting: The dashboard looks at your EWMA trend and estimates roughly how much time you have left (e.g., "~14 Days Remaining"), making it a bit easier to plan battery swaps.
  • Parasitic Drain Detection: The engine tracks what "normal" looks like for each device and will flag units that suddenly start dumping voltage rapidly (which can happen during routing loops or firmware issues) with a Yellow Warning.
  • Outdoor Thermal Profiles: For sensors in freezing environments (like a greenhouse or patio), you can now enable an "Outdoor Thermal Profile." This heavily dampens the EWMA algorithm to ignore massive winter temperature swings and reduce false alarms.
  • Per-Device Threshold Overrides: You can now override the global battery threshold on a per-device basis. For example, you can set a heavy Z-Wave deadbolt to warn you at 35%, while letting a low-power contact sensor run down to 5%.

:package: 3. The Battery Locker & 12-Month Procurement Forecasting

To help keep track of battery inventory across larger homes, we've integrated a dedicated management modal.

  • Dynamic Inventory: The dashboard calculates exactly what batteries (and how many) power your monitored devices.
  • Annual Burn Rate Forecasting: Using the live EWMA drop rates, the dashboard projects roughly how many AA, CR123A, or CR2032 cells your estate will consume over the next 365 days.
  • Smart Shopping List: The Battery Locker compares your "Spares on Hand", the "Replace Now" count, and your "12-Month Forecast" to help you figure out exactly what you might need to buy in bulk.

:spider_web: 4. Automated Mesh Topology Protection

When a hardwired repeater (like a smart plug) goes offline, surrounding sleepy battery devices can quickly drain their batteries trying to route through it.

  • Spatial Threat Mapping: The engine now maps your battery devices to your hardwired routers by their assigned physical location.
  • Proactive Ghost Node Warnings: If a smart plug goes offline in your "Garage", the system will flag the battery sensors in that same location with a ":warning: Mesh Risk: Repeater Offline" warning, so you know to check the plug before the sensors drain themselves.

:arrows_counterclockwise: 5. Auto-Heal Physical Power Cycling

Sometimes standard software pings aren't enough to wake up a stubborn switch.

  • Physical State Toggling: If a switch or plug falls off the mesh and standard pings fail, the Auto-Heal engine can now read its physical state and send a toggle command (Off -> On, or On -> Off) to try and force it back onto the mesh.
  • Safety Limits & Opt-Outs: This is strictly limited to once every 24 hours per device. You can also explicitly opt-out specific plugs (like those attached to PCs, routers, or sensitive electronics) directly in the app settings.

:computer_mouse: 6. Interactive Two-Way Portal

The dashboard has been updated to function as a two-way configuration tool.

  • Drag-and-Drop Layout: Click ":pencil2: Edit Layout" to enable drag-and-drop sorting on your category folders. The portal silently saves your new priority order directly back to Hubitat.
  • Dynamic Grouping: You can now toggle the dashboard view from "Group by Type" (Folders) to "Group by Room" (Locations) via a dropdown on the top navigation bar.
  • Two-Way Sync Modals: Clicking a device card opens its details. You can edit the device's Location, Description, Battery Type, Battery Quantity, and Override Thresholds directly from the web portal. Clicking "Save" instantly updates the app settings in Hubitat.
  • Hub Telemetry: A new dropdown on the main screen provides your live Hub Firmware, OS Memory (Free/Total), Database Size, and System Uptime (translated into Days, Hours, Minutes, Seconds).

A huge thank you to everyone who has tested earlier versions, shared logs, and provided feedback to help shape this. The updated code is available now on GitHub.

Give it a spin, try out the new SPA portal, and let me know how it runs for you. Bug reports and suggestions are always welcome!

APP:
raw.githubusercontent.com/ShaneAllen334/Hubitat_Apps/refs/heads/main/Advanced_Device_Health_Monitor/Advanced_Device_Health_Monitor.groovy

Driver:
raw.githubusercontent.com/ShaneAllen334/Hubitat_Apps/refs/heads/main/Advanced_Device_Health_Monitor/Advanced_Device Health_Monitor_Information.groovy

Thanks for another great app. A couple of things I've run into.

When selecting devices the Select All & Unselect All buttons do not work for me.

Going into Notification Rules & Routing I found this already there:

Thanks for your time.

That pretty funny, I left my notification devices hard coded. I'll get this corrected and look into the Select All.

Thanks for the feedback.

1 Like

Fix 1.5.4 is available.

  • Fixed notification devices from being hardcoded.
  • Fixed select all, and unselect all. *Note if a device has a special character the feature will unfortunate fail" a work around will hopefully be added in the future.

Thanks for the insanely quick response.

Notification devices, all good.

Select All/Unselect All still not working for me. I do not have "an apostrophe ('), ampersand (&), or quote (")" in any of the names.

I just realized that lights I added were turned on by the app. Not all, just about 6 or so.

Sorry, forgot to included headings

You will have to add them to the list of devices to ignore power on/off commands. I added a feature that if a refresh command doesn't bring the device back to life it will try to turn the device on then off, or off then on to bring it back to life.

-This will only happen every once every 24 hours if it things the device is offline.
-I'll continue to look into the select all.

I updated both the driver and app and since doing so I'm getting an error.
I uninstalled and re-installed the app/device and now nothing is showing in the dashboard.
Here is the error.

app:13752026-05-18 18:47:24.784 error > groovy.lang.MissingMethodException: No signature of method: user_app_ShaneAllen_Advanced_Device_Health_Monitor_630.updateChildHtmlDashboard() is applicable for argument types: (java.util.ArrayList, java.lang.Integer, java.lang.Integer) values: [[[customLoc:, lastActive:05/18/26 5:07 PM, isMains:false, battThreshOverride:, ...], ...], ...] on line 1111 (method finalizeScan)

Force a sync. I'll look into this drive code.

Yes.
Here is a screenshot of the logs.

Looking into this now.

Nailed it.
Oops. I see you've deleted your post.
It is working OK now though. :+1:

1 Like

Additional issues are being resolved in the next update patch.

Version 1.5.8 is available

-Bug fixes
-Select All, and Unselect All are unfortunately not working for the foreseeable future until a work around can be applied.

Version 1.5.10 is available

  • Light mode
  • Faster restored devices

-If a device is in critical or warning the application will pull the battery trend data to create a graph so you can see a live picture of what's going on with the battery life.

-The next update will re-introduce the device type, hardware type, firmware, and battery selection on devices that are in critical or warning. All other devices won't show that information until an alert is present. This is to increase the loading speed on the cloud link as we are restricted to how much information can be pulled before a timeout prevents the page from loading.

1 Like

Odd characters appear when clicking on the Force Health Scan button of the Portal:

Γ°ΕΈβ€β€ž Stanndard BMS Syncing...

This is in the Firefox browser.

This is currently in all browsers. I've got to update the code to fix this, been lazy trying to hammer the other bugs I've discovered.

FIX per ChatGPT:

    return "<!DOCTYPE html><html><head><meta charset='UTF-8'><meta name='viewport' content='width=device-width, initial-scale=1'><script>setTimeout(function(){window.location.href='dashboard?access_token=${state.accessToken}';}, ${delayMs});</script></head><body style='background:#0d0d0d;color:#fff;text-align:center;padding-top:100px;font-family:sans-serif;'><h3>&#128260; Standard BMS Syncing...</h3><p style='color:#666;'>${msgText}</p></body></html>"

ChatGPT explanation:

The browser is interpreting the UTF-8 emoji bytes as a non-UTF-8 character set.

Use both fixes:

Add an explicit UTF-8 charset meta tag.
Replace the raw emoji with an HTML numeric entity.
1 Like

Version 2.0 Available

1. Firmware Diagnostic Visibility Fix

  • The Issue: Devices flagged with "FW Mismatch" were being treated as "Healthy" by the system, which hid the adv-stat-row (Model, Firmware, Driver) in the modal.
  • The Fix: We updated the isHealthy calculation in both the Backend (serveDataEndpoint) and the Frontend (openDeviceModal). The system now explicitly checks for the "FW Mismatch" string, ensuring that diagnostic details remain visible for those devices even if their status is "Blue."

2. UI Header Cleanup

  • The Issue: You had a redundant "Device Health Command Center" header appearing twice on the main Hubitat app configuration page.
  • The Fix: We removed the hardcoded paragraph and section block containing the duplicate header in mainPage() and consolidated the versioning into the main dynamicPage title for a cleaner, professional look.

3. Battery Locker Modal Optimization

  • The Issue: The internal scroll bar inside the Battery Locker modal was making it difficult to read the inventory numbers.
  • The Fix: We removed the fixed max-height and overflow-y constraints from the batteryLockerModalBody container. This allows the modal to expand naturally and rely on the main modal's viewport-height-aware scrolling, making the data much easier to scan.