Files
NetAlertX/docs
Mauricio Camayo e543f14d08 fix: address round 2 of jokob-sk's maintainer review
References PR #1765.

Docs:
- Added PIHOLEMON to docs/PLUGINS.md and a new "Approach 4" section in
  docs/PIHOLE_GUIDE.md, leading with anomaly detection (the actual
  differentiator vs PIHOLEAPI) and explaining when to pick each plugin.
- README/PLUGINS.md/config.json's UI-facing description all reordered
  and shortened to lead with anomaly detection instead of device
  import, and to drop implementation detail that belongs in the
  README, not the Settings page.
- Trimmed the "Why not extend PIHOLEAPI" README section per feedback -
  useful context for a maintainer, not for an end user configuring
  the plugin.

config.json / pihole_monitor.py:
- RUN defaults to "disabled", matching every other non-core plugin.
- VERIFY_SSL split into PRIMARY_VERIFY_SSL / SECONDARY_VERIFY_SSL -
  each instance can be http/https independently. Settings reordered so
  each *_VERIFY_SSL sits right under its matching *_PASSWORD.
- GRAPHQL_TOKEN removed; graphql_token now reads the core API_TOKEN
  setting instead of a plugin-specific duplicate.
- GRAPHQL_URL replaced with a GET_OWNER boolean - the endpoint is now
  derived from this app's own GRAPHQL_PORT (single source of truth)
  instead of a URL the user had to keep in sync by hand.
- HISTORY_LENGTH (run count) replaced with HISTORY_DAYS (a real time
  window): state now stores [timestamp, delta] samples and
  trim_history() drops anything older than the window, so the
  baseline means the same thing regardless of schedule - a faster
  schedule adds more data points instead of shrinking the window.
- STATE_FILE moved from the log folder to dbFolderPath, so the rolling
  anomaly baseline survives NetAlertX upgrades instead of being wiped
  with the logs.
- netalertx_device_owner() (1 GraphQL call per device) replaced by
  netalertx_device_owners() (1 call per run, batched) - avoids N
  blocking round-trips on a large network.
- Fixed a zero-baseline bug: `bool(... and baseline and ...)` silently
  exempted a device with an all-zero blocked-query history (0.0 is
  falsy in Python) from ever being flagged, even on its first real
  spike. Now checks `baseline is not None`.
- Fixed the placeholder-MAC filter: only excluded the literal "ip-::",
  not Pi-hole's general "ip-<address>" placeholder pattern. Caught
  downstream by is_mac() either way, but now the actual placeholder
  check does what it looks like it does.
- Fixed a cumulative-counter bug: Pi-hole's /api/stats/top_clients
  returns a count that's cumulative since FTL last started, not a
  per-interval or daily-resetting one (confirmed against FTL's own
  source and long-standing user reports that it doesn't reset at
  midnight). Comparing that raw total directly against a rolling
  average made any device's ordinary growing traffic look like an
  escalating anomaly. compute_delta() now diffs each run's raw count
  against the previous run's (state gained a per-key last_raw
  reference point alongside the delta history) - None (not 0) on the
  first-ever run for a device or right after a counter reset, so
  those runs re-anchor the reference point instead of fabricating or
  swallowing a delta.
- RUN_SCHD default changed from every 6 hours to every 5 minutes now
  that the baseline window is real days, not run count, so a frequent
  schedule only adds data points instead of narrowing the window; also
  matches the default most other device-scanner plugins use.
- RUN_SCHD gained the same live cron-validity checkmark ARPSCAN and
  other scanner plugins use (a ✓/✗ icon next to the field, validated
  client-side against a regex) - reuses the existing generic
  validateRegex() widget, nothing plugin-specific to build.

Tests: 48 tests (up from 37), 99% line+branch coverage. Every fix
above verified via mutation testing (deliberately broken, confirmed
the relevant test fails, then restored).
2026-08-31 11:49:02 -05:00
..
2026-07-30 07:38:07 +10:00
2026-07-25 10:25:33 +10:00
2026-07-25 10:25:33 +10:00
2026-08-05 11:15:51 +10:00
2026-08-05 11:15:51 +10:00
2026-07-25 10:25:33 +10:00

Documentation overview

In the app hover over settings or fields/labels or click blue in-app (question-mark) icons to get to relevant documentation pages.

In-app help

There is also an in-app Help / FAQ section that should be answering frequently asked questions.

📥 Installation

🐳 Docker (Fully supported)

💻 Bare-metal / On-server (Experimental/community supported 🧪)

📚 Table of contents

📥 Initial Setup

🐛 Debugging help & tips

🔝 Popular/Suggested

⚙ System Management

🔎 Examples

♻ Misc

👩‍💻For Developers👨‍💻

Feel free to suggest or submit new docs via a PR.

👨‍💻 Development priorities

Priorities from highest to lowest:

  • 🔼 Fixing core functionality bugs not solvable with workarounds
  • 🔵 New core functionality unlocking other opportunities (e.g.: plugins)
  • 🔵 Refactoring enabling faster implementation of future functionality
  • 🔽 (low) UI functionality & improvements (PRs welcome 😉)

Design philosophy: Focus on core functionality and leverage existing apps and tools to make NetAlertX integrate into other workflows.

Examples:

1. Supporting apprise makes more sense than implementing multiple individual notification gateways
2. Implementing regular expression support across settings for validation makes more sense than validating one setting with a specific expression.

UI-specific requests are a low priority as the framework picked by the original developer is not very extensible (and afaik doesn't support components) and has limited mobile support. Also, I argue the value proposition is smaller than working on something else.

Feel free to submit PRs if interested. try to keep the PRs small/on-topic so they are easier to review and approve.

That being said, I'd reconsider if more people and or recurring sponsors file a request 😉.

🙏 Feature requests

Please be as detailed as possible with workarounds you considered and why a native feature is the better way. This gives me better context and will make it more likely to be implemented. Ideally, a feature request should be in the format "I want to be able to do XYZ so that ZYX. I considered these approaches XYZ".

Pull requests (PRs)

If you submit a PR please:

  1. Check that your changes are backward compatible with existing installations and with a blank setup.
  2. Existing features should always be preserved.
  3. Keep the PR small, on-topic and don't change code that is not necessary for the PR to work
  4. New features code should ideally be re-usable for different purposes, not for a very narrow use case.
  5. New functionality should ideally be implemented via the Plugins system, if possible.

Suggested test cases:

  • Blank setup with no DB or config
  • Existing DB / config
  • Sending a notification (e. g. Delete a device and wait for a scan to run) and testing all notification gateways, especially:
    • Email, Apprise (e.g. via Telegram), webhook (e.g. via Discord), MQTT (e.g. via Home Assistant)
  • Saving settings
  • Test a couple of plugins
  • Check the Error log for anything unusual

Some additional context:

  • Permanent settings/config is stored in the app.conf file
  • Currently temporary (session?) settings are stored in the Parameters DB table as key-value pairs. This table is wiped during a container rebuild/restart and its values are re-initialized from cookies/session data from the browser.

🐛 Submitting an issue or bug

Before submitting a new issue please spend a couple of minutes on research:

⚠ Please follow the pre-defined issue template to resolve your issue faster.