fix: compute ETA using measured tick rate

This commit is contained in:
2026-08-02 16:44:12 +08:00
parent ea288b6572
commit 23196cd59d
+25 -10
View File
@@ -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, {