tune: stabilize approaching trigger and show precise ETA
This commit is contained in:
+58
-7
@@ -2,7 +2,7 @@
|
||||
-- ============================================================================
|
||||
-- 1. Configuration & Constants
|
||||
-- ============================================================================
|
||||
local APP_VERSION_TEXT = "v1.0.41"
|
||||
local APP_VERSION_TEXT = "v1.0.42"
|
||||
|
||||
local CONFIG = {
|
||||
CLOUD_URL = "ws://stabadmin.fse-media.group",
|
||||
@@ -18,6 +18,7 @@ local CONFIG = {
|
||||
ALERT_CONFIRM_MS = 60000,
|
||||
ALERT_COOLDOWN_MS = 300000,
|
||||
APPROACHING_COOLDOWN_MS = 120000,
|
||||
APPROACHING_STABLE_MS = 15000,
|
||||
DEBUG = true
|
||||
}
|
||||
|
||||
@@ -2406,7 +2407,15 @@ local function buildEtaLabel(etaSeconds, textEta)
|
||||
return "~" .. tostring(value) .. "m"
|
||||
end
|
||||
end
|
||||
return tostring(math.max(0, tonumber(etaSeconds) or 0)) .. "s"
|
||||
local secs = math.max(0, tonumber(etaSeconds) or 0)
|
||||
local whole = math.floor(secs + 0.0001)
|
||||
if whole >= 60 then
|
||||
return string.format("%02d:%02d", math.floor(whole / 60), whole % 60)
|
||||
end
|
||||
if secs >= 10 then
|
||||
return string.format("%02ds", whole)
|
||||
end
|
||||
return string.format("%.1fs", secs)
|
||||
end
|
||||
|
||||
local function mapTrainStatusReason(statusId)
|
||||
@@ -2494,6 +2503,7 @@ 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 = {}
|
||||
local seenApproachKeys = {}
|
||||
|
||||
cleanupTimestampMap(State.announcedApproaching, now, tonumber(CONFIG.APPROACHING_COOLDOWN_MS) or 120000)
|
||||
cleanupTimestampMap(State.announcedAlerts, now, tonumber(CONFIG.ALERT_COOLDOWN_MS) or 300000)
|
||||
@@ -2529,7 +2539,7 @@ function Main.loop()
|
||||
local scheduledArrival = pickEarlierTick(st.ScheduledArrival, st.ScheduledDeparture)
|
||||
local realArrival = pickEarlierTick(st.RealTimeArrival, st.RealTimeDeparture)
|
||||
local etaTicks = realArrival - currentTick
|
||||
local etaSeconds = math.floor(etaTicks / (State.tickRate or 20))
|
||||
local etaSeconds = etaTicks / (State.tickRate or 20)
|
||||
if etaSeconds < 0 then etaSeconds = 0 end
|
||||
local announceKey = normalizeUpcomingKey(trainName, destination)
|
||||
local etaLabel = buildEtaLabel(etaSeconds, etaTextByKey[announceKey])
|
||||
@@ -2575,9 +2585,22 @@ function Main.loop()
|
||||
end
|
||||
|
||||
if etaSeconds >= 0 and etaSeconds < 30 then
|
||||
if not State.announcedApproaching[announceKey] then
|
||||
seenApproachKeys[announceKey] = true
|
||||
local pending = State.pendingApproaching[announceKey]
|
||||
if not pending then
|
||||
State.pendingApproaching[announceKey] = { since = now, lastEta = etaSeconds }
|
||||
else
|
||||
if etaSeconds > (tonumber(pending.lastEta) or etaSeconds) + 0.5 then
|
||||
pending.since = now
|
||||
end
|
||||
pending.lastEta = etaSeconds
|
||||
end
|
||||
|
||||
local stableMs = tonumber(CONFIG.APPROACHING_STABLE_MS) or 15000
|
||||
local currentPending = State.pendingApproaching[announceKey]
|
||||
if currentPending and (now - (currentPending.since or now)) >= stableMs and not State.announcedApproaching[announceKey] then
|
||||
State.announcedApproaching[announceKey] = now
|
||||
Utils.log("INFO", string.format("Train Approaching: %s (ETA: %ds, Delay: %dm)", trainName, etaSeconds, delayMinutes))
|
||||
Utils.log("INFO", string.format("Train Approaching: %s (ETA: %.1fs, Delay: %dm)", trainName, etaSeconds, delayMinutes))
|
||||
Network.send({
|
||||
type = "train_approaching",
|
||||
stationName = State.stationName,
|
||||
@@ -2585,13 +2608,15 @@ function Main.loop()
|
||||
stationPlatform = platform,
|
||||
trainId = trainName,
|
||||
destination = destination,
|
||||
eta = tostring(etaSeconds) .. "s",
|
||||
eta = string.format("%.1fs", etaSeconds),
|
||||
etaSeconds = etaSeconds,
|
||||
delay = displayDelayMinutes,
|
||||
cancelled = cancelled,
|
||||
reason = reason
|
||||
})
|
||||
end
|
||||
else
|
||||
State.pendingApproaching[announceKey] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -2601,6 +2626,11 @@ function Main.loop()
|
||||
State.pendingAlerts[k] = nil
|
||||
end
|
||||
end
|
||||
for k, _ in pairs(State.pendingApproaching) do
|
||||
if not seenApproachKeys[k] then
|
||||
State.pendingApproaching[k] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2608,6 +2638,7 @@ function Main.loop()
|
||||
if not Peripherals.blockReader and Peripherals.createTarget then
|
||||
local lines = Peripherals.createTarget.dump()
|
||||
local seenAlertKeys = {}
|
||||
local seenApproachKeys = {}
|
||||
|
||||
cleanupTimestampMap(State.announcedApproaching, now, tonumber(CONFIG.APPROACHING_COOLDOWN_MS) or 120000)
|
||||
cleanupTimestampMap(State.announcedAlerts, now, tonumber(CONFIG.ALERT_COOLDOWN_MS) or 300000)
|
||||
@@ -2687,7 +2718,20 @@ function Main.loop()
|
||||
|
||||
-- 触发逻辑:当 ETA 已经明确小于30秒(包括15秒、现在等),且之前没有播报过
|
||||
if etaSeconds >= 0 and etaSeconds < 30 then
|
||||
if not State.announcedApproaching[announceKey] then
|
||||
seenApproachKeys[announceKey] = true
|
||||
local pending = State.pendingApproaching[announceKey]
|
||||
if not pending then
|
||||
State.pendingApproaching[announceKey] = { since = now, lastEta = etaSeconds }
|
||||
else
|
||||
if etaSeconds > (tonumber(pending.lastEta) or etaSeconds) + 0.5 then
|
||||
pending.since = now
|
||||
end
|
||||
pending.lastEta = etaSeconds
|
||||
end
|
||||
|
||||
local stableMs = tonumber(CONFIG.APPROACHING_STABLE_MS) or 15000
|
||||
local currentPending = State.pendingApproaching[announceKey]
|
||||
if currentPending and (now - (currentPending.since or now)) >= stableMs and not State.announcedApproaching[announceKey] then
|
||||
State.announcedApproaching[announceKey] = now
|
||||
Utils.log("INFO", string.format("Train Approaching: %s (ETA: %ds, Delay: %dm)", tName, etaSeconds, delay))
|
||||
Network.send({
|
||||
@@ -2702,6 +2746,8 @@ function Main.loop()
|
||||
delay = delay
|
||||
})
|
||||
end
|
||||
else
|
||||
State.pendingApproaching[announceKey] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -2712,6 +2758,11 @@ function Main.loop()
|
||||
State.pendingAlerts[k] = nil
|
||||
end
|
||||
end
|
||||
for k, _ in pairs(State.pendingApproaching) do
|
||||
if not seenApproachKeys[k] then
|
||||
State.pendingApproaching[k] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Update Upcoming Trains globally for the monitor
|
||||
|
||||
Reference in New Issue
Block a user