tune: add delay confirmation and approaching cooldown
This commit is contained in:
+44
-23
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user