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

View File

@@ -68,41 +68,6 @@ sql_devices_all = """
"""
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 = """
SELECT DISTINCT 'devSite' AS columnName, devSite AS columnValue
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")
# -------------------------------------------------------------------------------
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
def row_to_json(names, row):