Refactor device tiles SQL logic to use get_sql_devices_tiles function for improved maintainability Feature Request - Flapping and Sleeping nuances

Fixes #1567
This commit is contained in:
Jokob @NetAlertX
2026-03-21 21:10:37 +00:00
parent 7569923481
commit fa22523a0b
3 changed files with 51 additions and 37 deletions

View File

@@ -18,9 +18,9 @@ from const import (
sql_language_strings, sql_language_strings,
sql_notifications_all, sql_notifications_all,
sql_online_history, sql_online_history,
sql_devices_tiles,
sql_devices_filters, sql_devices_filters,
) )
from db.db_helper import get_sql_devices_tiles
from logger import mylog from logger import mylog
from helper import write_file, get_setting_value from helper import write_file, get_setting_value
from utils.datetime_utils import timeNowUTC from utils.datetime_utils import timeNowUTC
@@ -67,7 +67,7 @@ def update_api(
["plugins_language_strings", sql_language_strings], ["plugins_language_strings", sql_language_strings],
["notifications", sql_notifications_all], ["notifications", sql_notifications_all],
["online_history", sql_online_history], ["online_history", sql_online_history],
["devices_tiles", sql_devices_tiles], ["devices_tiles", get_sql_devices_tiles()],
["devices_filters", sql_devices_filters], ["devices_filters", sql_devices_filters],
["custom_endpoint", conf.API_CUSTOM_SQL], ["custom_endpoint", conf.API_CUSTOM_SQL],
] ]

View File

@@ -68,41 +68,6 @@ sql_devices_all = """
""" """
sql_appevents = """select * from AppEvents order by dateTimeCreated desc""" sql_appevents = """select * from AppEvents order by dateTimeCreated desc"""
# The below query calculates counts of devices in various categories:
# (connected/online, offline, down, new, archived),
# as well as a combined count for devices that match any status listed in the UI_MY_DEVICES setting
sql_devices_tiles = """
WITH Statuses AS (
SELECT setValue
FROM Settings
WHERE setKey = 'UI_MY_DEVICES'
),
MyDevicesFilter AS (
SELECT
-- Build a dynamic filter for devices matching any status in UI_MY_DEVICES
devPresentLastScan, devAlertDown, devIsNew, devIsArchived
FROM Devices
WHERE
(instr((SELECT setValue FROM Statuses), 'online') > 0 AND devPresentLastScan = 1) OR
(instr((SELECT setValue FROM Statuses), 'offline') > 0 AND devPresentLastScan = 0 AND devIsArchived = 0) OR
(instr((SELECT setValue FROM Statuses), 'down') > 0 AND devPresentLastScan = 0 AND devAlertDown = 1) OR
(instr((SELECT setValue FROM Statuses), 'new') > 0 AND devIsNew = 1) OR
(instr((SELECT setValue FROM Statuses), 'archived') > 0 AND devIsArchived = 1)
)
SELECT
-- Counts for each individual status
(SELECT COUNT(*) FROM Devices WHERE devPresentLastScan = 1) AS connected,
(SELECT COUNT(*) FROM Devices WHERE devPresentLastScan = 0) AS offline,
(SELECT COUNT(*) FROM Devices WHERE devPresentLastScan = 0 AND devAlertDown = 1) AS down,
(SELECT COUNT(*) FROM Devices WHERE devIsNew = 1) AS new,
(SELECT COUNT(*) FROM Devices WHERE devIsArchived = 1) AS archived,
(SELECT COUNT(*) FROM Devices WHERE devFavorite = 1) AS favorites,
(SELECT COUNT(*) FROM Devices) AS "all",
(SELECT COUNT(*) FROM Devices) AS "all_devices",
-- My Devices count
(SELECT COUNT(*) FROM MyDevicesFilter) AS my_devices
FROM Statuses;
"""
sql_devices_filters = """ sql_devices_filters = """
SELECT DISTINCT 'devSite' AS columnName, devSite AS columnValue SELECT DISTINCT 'devSite' AS columnName, devSite AS columnValue
FROM Devices WHERE devSite NOT IN ('', 'null') AND devSite IS NOT NULL FROM Devices WHERE devSite NOT IN ('', 'null') AND devSite IS NOT NULL

View File

@@ -66,6 +66,55 @@ def get_device_condition_by_status(device_status):
return get_device_conditions().get(device_status, "WHERE 1=0") return get_device_conditions().get(device_status, "WHERE 1=0")
# -------------------------------------------------------------------------------
def get_sql_devices_tiles():
"""Build the device tiles count SQL using get_device_conditions() to avoid duplicating filter logic."""
conds = get_device_conditions()
def f(key):
"""Strip 'WHERE ' prefix for use inside SELECT subqueries."""
return conds[key][len("WHERE "):]
# UI_MY_DEVICES setting values mapped to their device_conditions keys
my_devices_setting_map = [
("online", "connected"),
("offline", "offline"),
("down", "down"),
("new", "new"),
("archived", "archived"),
]
my_devices_clauses = "\n OR ".join(
f"(instr((SELECT setValue FROM Statuses), '{sk}') > 0 AND {f(ck)})"
for sk, ck in my_devices_setting_map
)
return f"""
WITH Statuses AS (
SELECT setValue
FROM Settings
WHERE setKey = 'UI_MY_DEVICES'
),
MyDevicesFilter AS (
SELECT devMac
FROM Devices
WHERE
{my_devices_clauses}
)
SELECT
(SELECT COUNT(*) FROM Devices WHERE {f('connected')}) AS connected,
(SELECT COUNT(*) FROM Devices WHERE {f('offline')}) AS offline,
(SELECT COUNT(*) FROM Devices WHERE {f('down')}) AS down,
(SELECT COUNT(*) FROM Devices WHERE {f('new')}) AS new,
(SELECT COUNT(*) FROM Devices WHERE {f('archived')}) AS archived,
(SELECT COUNT(*) FROM Devices WHERE {f('favorites')}) AS favorites,
(SELECT COUNT(*) FROM Devices WHERE {f('all')}) AS "all",
(SELECT COUNT(*) FROM Devices) AS "all_devices",
(SELECT COUNT(*) FROM MyDevicesFilter) AS my_devices
FROM Statuses;
"""
# ------------------------------------------------------------------------------- # -------------------------------------------------------------------------------
# Creates a JSON-like dictionary from a database row # Creates a JSON-like dictionary from a database row
def row_to_json(names, row): def row_to_json(names, row):