Files
NetAlertX/server
sebingel d15b682b51 makes PIHOLEAPI decide online status from the device lastQuery
Devices reported by PIHOLEAPI stayed online for about 24 hours after they
left the network (follow-up to #1436). The online check compared
PIHOLEAPI_CONSIDER_ONLINE with the freshest ips[].lastSeen of a device.
Pi-hole FTL v6.8 sets lastSeen to "now" on every network table update for
every client it still holds in memory, also when the client is not in the
ARP cache (src/database/network-table.c, add_FTL_clients_to_network_table()
calls add_netDB_network_address()). In a live run against Pi-hole v6.8 all
22 devices the old code reported as online had a lastSeen of 36 s, among
them a phone whose last DNS query was 18 h old.

Changes:
- New is_device_online(last_query, now_ts, consider_online) in
  server/plugins/pihole_api_scan/pihole_api_scan.py. A device is online if
  its last DNS query is at most consider_online seconds old; a lastQuery
  of 0 (never queried) is always offline.
- gather_device_entries() reads the device lastQuery instead of looping
  over ips[].lastSeen, and each entry carries 'isOnline'. The 'lastQuery'
  field (shown as "Last Query") now holds the real lastQuery.
- PIHOLEAPI_CONSIDER_ONLINE gets a module-level default of 300, like the
  other setting globals.
- The verbose line for a skipped offline device names the MAC and the
  age of its last DNS query instead of dumping the whole device dict.
- config.json: CONSIDER_ONLINE is labeled "Online if last query" and its
  description says the window applies to the last DNS query.
- README: lists "Time of the last DNS query" and explains that online
  status comes from DNS activity, that quiet devices can show as offline,
  and what to do (presence scanner on the same schedule, or a larger
  CONSIDER_ONLINE when PIHOLEAPI is the only presence source).
- New test/plugins/test_pihole_api_scan.py (module stubs as in
  test_adguard_import.py): the reported case, the CONSIDER_ONLINE
  boundary, clock skew, a missing or zero lastQuery, a device with two
  IPs. All 10 tests fail on the old code.

Impact:
A device goes offline in PIHOLEAPI CONSIDER_ONLINE seconds after its last
DNS query, not about 24 hours later. Behavior change: a device that is on
but sends no DNS query within that window is not reported as online by
PIHOLEAPI any more. Setting keys and defaults are unchanged.
2026-11-01 09:29:02 +00:00
..
…
…
…
…
…
…
…
…
…

NetAlertX modules

The original pilaert.py code is now moved to this new folder and split into different modules.

Module Description
__main__.py The MAIN program of NetAlertX
__init__.py an empty init file
README.md this readme file
../server/plugins a folder containing all plugins that publish notifications or scan for devices
api.py updating the API endpoints with the relevant data.
appevent.py TBC
const.py A place to define the constants for NetAlertX like log path or config path.
conf.py conf.py holds the configuration variables and makes them available for all modules. It is also the workaround for global variables that need to be resolved at some point
database.py This module connects to the DB, makes sure the DB is up to date and defines some standard queries and interfaces.
device.py The device module looks after the devices and saves the scan results into the devices
flows.py TBC
helper.py Helper as the name suggest contains multiple little functions and methods used in many of the other modules and helps keep things clean
initialise.py Initiatlise sets up the environment and makes everything ready to go
logger.py Logger is there the keep all the logs organised and looking identical.
networscan.py Networkscan collects the scan results (maybe to merge with reporting.py)
notification.py Creates and handles the notification object and generates ther HTML and text variants of the message
plugin.py This is where the plugins get integrated into the backend of NetAlertX
plugin_utils.py Helper utilities for plugin.py
reporting.py Reporting collects the data for the notification reports
scheduler.py All things scheduling