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