From 23196cd59db96aa0373de7d78487f668764b035d Mon Sep 17 00:00:00 2001 From: HenryDu8133 <813367384@qq.com> Date: Sun, 2 Aug 2026 16:44:12 +0800 Subject: [PATCH] fix: compute ETA using measured tick rate --- station_broadcast.lua | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/station_broadcast.lua b/station_broadcast.lua index 27f5cac..04c3361 100644 --- a/station_broadcast.lua +++ b/station_broadcast.lua @@ -2,7 +2,7 @@ -- ============================================================================ -- 1. Configuration & Constants -- ============================================================================ -local APP_VERSION_TEXT = "v1.0.29" +local APP_VERSION_TEXT = "v1.0.30" local CONFIG = { CLOUD_URL = "ws://stabadmin.fse-media.group", @@ -51,7 +51,8 @@ local State = { currentPlaying = nil, currentPriority = -1, interruptSeq = 0, - debugUpcoming = nil + debugUpcoming = nil, + tickRate = 20 } -- ============================================================================ @@ -2139,11 +2140,12 @@ function Display.render() mon.setTextColor(COLORS.DEBUG) local dbg = State.debugUpcoming local dbgLine = string.format( - "SRC BR:%s CT:%s OK:%s TS:%s", + "SRC BR:%s CT:%s OK:%s TS:%s TPS:%s", dbg.hasBR and "Y" or "N", dbg.hasCT and "Y" or "N", dbg.ok and "Y" or "N", - tostring(dbg.trainStopsCount or 0) + tostring(dbg.trainStopsCount or 0), + tostring(math.floor((dbg.tickRate or 20) * 10) / 10) ) if #dbgLine > w then dbgLine = dbgLine:sub(1, w) end mon.write(dbgLine) @@ -2333,7 +2335,8 @@ function Main.loop() hasBR = Peripherals.blockReader ~= nil, hasCT = Peripherals.createTarget ~= nil, ok = false, - trainStopsCount = 0 + trainStopsCount = 0, + tickRate = State.tickRate or 20 } -- Check Block Reader (Advanced Peripherals) first for precise ETA and Delay @@ -2347,13 +2350,25 @@ function Main.loop() for _ in pairs(data.TrainStops) do c = c + 1 end end dbg.trainStopsCount = c - -- Real-time interpolation: calculate exact current tick even if NBT is cached + -- Real-time interpolation: estimate actual tick rate (TPS) from CRN refreshes if not State.lastRefreshed or State.lastRefreshed ~= data.LastRefreshed then + if State.lastRefreshed and State.lastRefreshedEpoch then + local deltaTicks = (data.LastRefreshed or 0) - (State.lastRefreshed or 0) + local deltaSeconds = (now - (State.lastRefreshedEpoch or now)) / 1000 + if deltaTicks > 0 and deltaSeconds > 0 then + local rate = deltaTicks / deltaSeconds + if rate < 1 then rate = 1 end + if rate > 20 then rate = 20 end + State.tickRate = rate + end + end State.lastRefreshed = data.LastRefreshed State.lastRefreshedEpoch = now end - local elapsedTicks = math.floor((now - (State.lastRefreshedEpoch or now)) / 50) - local currentTick = (data.LastRefreshed or 0) + elapsedTicks + dbg.tickRate = State.tickRate or 20 + + local elapsedSeconds = (now - (State.lastRefreshedEpoch or now)) / 1000 + local currentTick = (data.LastRefreshed or 0) + math.floor(elapsedSeconds * (State.tickRate or 20)) for k, v in pairs(State.announcedApproaching) do if now - v > 300000 then @@ -2396,12 +2411,12 @@ function Main.loop() local scheduledArrival = st.ScheduledArrival or 0 local realArrival = st.RealTimeArrival or 0 local etaTicks = realArrival - currentTick - local etaSeconds = math.floor(etaTicks / 20) + local etaSeconds = math.floor(etaTicks / (State.tickRate or 20)) if etaSeconds < 0 then etaSeconds = 0 end -- Calculate Delay in minutes local delayTicks = realArrival - scheduledArrival - local delayMinutes = math.floor(delayTicks / (20 * 60)) + local delayMinutes = math.floor(delayTicks / ((State.tickRate or 20) * 60)) if delayMinutes < 0 then delayMinutes = 0 end table.insert(newUpcoming, {