tune: add delay confirmation and approaching cooldown

This commit is contained in:
2026-08-02 19:22:01 +08:00
parent 04591fc0c8
commit fb1256fbcc
+44 -23
View File
@@ -2,7 +2,7 @@
-- ============================================================================
-- 1. Configuration & Constants
-- ============================================================================
local APP_VERSION_TEXT = "v1.0.40"
local APP_VERSION_TEXT = "v1.0.41"
local CONFIG = {
CLOUD_URL = "ws://stabadmin.fse-media.group",
@@ -15,6 +15,9 @@ local CONFIG = {
STATION_IDENTITY_FILE = "station_identity.cfg",
AUDIO_VOLUME = 100,
AUDIO_STREAM_PREROLL_CHUNKS = 5,
ALERT_CONFIRM_MS = 60000,
ALERT_COOLDOWN_MS = 300000,
APPROACHING_COOLDOWN_MS = 120000,
DEBUG = true
}
@@ -2309,8 +2312,26 @@ end
local Main = {}
State.announcedApproaching = {}
State.announcedAlerts = {}
State.pendingAlerts = {}
State.pendingApproaching = {}
local function cleanupTimestampMap(map, now, maxAgeMs)
for k, v in pairs(map or {}) do
if now - v > maxAgeMs then
map[k] = nil
end
end
end
local function isPendingAlertReady(key, now)
local firstSeen = State.pendingAlerts[key]
if not firstSeen then
State.pendingAlerts[key] = now
return false
end
return (now - firstSeen) >= (tonumber(CONFIG.ALERT_CONFIRM_MS) or 60000)
end
local function parseEtaText(etaStr)
etaStr = tostring(etaStr or "")
if etaStr == "" then return -1 end
@@ -2472,17 +2493,10 @@ function Main.loop()
local elapsedSeconds = (now - (State.lastRefreshedEpoch or now)) / 1000
local currentTick = (data.LastRefreshed or 0) + math.floor(elapsedSeconds * (State.tickRate or 20))
local seenAlertKeys = {}
for k, v in pairs(State.announcedApproaching) do
if now - v > 300000 then
State.announcedApproaching[k] = nil
end
end
for k, v in pairs(State.announcedAlerts) do
if now - v > 300000 then
State.announcedAlerts[k] = nil
end
end
cleanupTimestampMap(State.announcedApproaching, now, tonumber(CONFIG.APPROACHING_COOLDOWN_MS) or 120000)
cleanupTimestampMap(State.announcedAlerts, now, tonumber(CONFIG.ALERT_COOLDOWN_MS) or 300000)
for i, stop in ipairs(data.TrainStops) do
local st = stop.Station
@@ -2540,7 +2554,8 @@ function Main.loop()
local alertType = cancelled and "cancelled" or ((displayDelayMinutes > 0) and "delayed" or nil)
local alertKey = alertType and (announceKey .. "::" .. alertType) or nil
if alertKey then
if not State.announcedAlerts[alertKey] then
seenAlertKeys[alertKey] = true
if isPendingAlertReady(alertKey, now) and not State.announcedAlerts[alertKey] then
State.announcedAlerts[alertKey] = now
Utils.log("INFO", string.format("Train Alert: %s (ETA: %ds, Delay: %dm, Cancelled: %s, Reason: %s)", trainName, etaSeconds, displayDelayMinutes, tostring(cancelled), tostring(reason or "")))
Network.send({
@@ -2580,23 +2595,22 @@ function Main.loop()
end
end
end
for k, _ in pairs(State.pendingAlerts) do
if not seenAlertKeys[k] then
State.pendingAlerts[k] = nil
end
end
end
end
-- Try CC:C Bridge Display Link (Legacy Text Parsing) if Block Reader is not available
if not Peripherals.blockReader and Peripherals.createTarget then
local lines = Peripherals.createTarget.dump()
local seenAlertKeys = {}
for k, v in pairs(State.announcedApproaching) do
if now - v > 300000 then
State.announcedApproaching[k] = nil
end
end
for k, v in pairs(State.announcedAlerts) do
if now - v > 300000 then
State.announcedAlerts[k] = nil
end
end
cleanupTimestampMap(State.announcedApproaching, now, tonumber(CONFIG.APPROACHING_COOLDOWN_MS) or 120000)
cleanupTimestampMap(State.announcedAlerts, now, tonumber(CONFIG.ALERT_COOLDOWN_MS) or 300000)
for _, lineText in pairs(lines) do
if lineText and lineText ~= "" and lineText:match("[%w%?%[]") then
@@ -2653,7 +2667,8 @@ function Main.loop()
local alertKey = announceKey .. "::delayed"
if delay > 0 then
if not State.announcedAlerts[alertKey] then
seenAlertKeys[alertKey] = true
if isPendingAlertReady(alertKey, now) and not State.announcedAlerts[alertKey] then
State.announcedAlerts[alertKey] = now
Utils.log("INFO", string.format("Train Delay Alert: %s (ETA: %ds, Delay: %dm)", tName, etaSeconds, delay))
Network.send({
@@ -2691,6 +2706,12 @@ function Main.loop()
end
end
end
for k, _ in pairs(State.pendingAlerts) do
if not seenAlertKeys[k] then
State.pendingAlerts[k] = nil
end
end
end
-- Update Upcoming Trains globally for the monitor