diff --git a/debug-upcoming-data-missing.md b/debug-upcoming-data-missing.md new file mode 100644 index 0000000..48379a1 --- /dev/null +++ b/debug-upcoming-data-missing.md @@ -0,0 +1,19 @@ +[OPEN] upcoming-data-missing + +## Symptom +- Monitor shows `NONE / WAITING DATA` under `UPCOMING TRAINS`. +- Expected: list of upcoming trains parsed from CRN advanced display NBT (TrainStops). + +## Hypotheses (falsifiable) +1. `Peripherals.blockReader` is not detected (wrong peripheral type string / not connected to this computer). +2. `blockReader.getBlockData()` succeeds but returns a table without `TrainStops` (block reader is pointing at the wrong block or advanced display data not present). +3. `TrainStops` exists but is not an array (non-numeric keys), so `ipairs()` iteration yields 0 rows. +4. `TrainStops` exists but the code path exits before assigning `State.upcomingTrains`. + +## Evidence to collect (instrumentation) +- Whether blockReader/create_target are detected. +- Whether getBlockData succeeds. +- Whether TrainStops exists and how many rows it contains (ipairs count vs pairs count). + +## Next action +- Add runtime instrumentation to display these values on the monitor and in logs. diff --git a/station_broadcast.lua b/station_broadcast.lua index dc9b002..6908ed3 100644 --- a/station_broadcast.lua +++ b/station_broadcast.lua @@ -50,7 +50,8 @@ local State = { audioQueue = {}, currentPlaying = nil, currentPriority = -1, - interruptSeq = 0 + interruptSeq = 0, + debugUpcoming = nil } -- ============================================================================ @@ -2115,6 +2116,21 @@ function Display.render() mon.setTextColor(COLORS.DEBUG) mon.setCursorPos(1, upcomingStartY) mon.write("UPCOMING TRAINS:") + if State.debugUpcoming and upcomingStartY + 1 <= h then + mon.setCursorPos(1, upcomingStartY + 1) + mon.setTextColor(COLORS.DEBUG) + local dbg = State.debugUpcoming + local dbgLine = string.format( + "SRC BR:%s CT:%s OK:%s TS:%s", + dbg.hasBR and "Y" or "N", + dbg.hasCT and "Y" or "N", + dbg.ok and "Y" or "N", + tostring(dbg.trainStopsCount or 0) + ) + if #dbgLine > w then dbgLine = dbgLine:sub(1, w) end + mon.write(dbgLine) + logsStartY = upcomingStartY + 2 + end if hasUpcoming then mon.setTextColor(COLORS.INFO) local visibleCount = math.min(3, #State.upcomingTrains, math.max(0, maxUpcomingRows - 1)) @@ -2126,15 +2142,17 @@ function Display.render() if #lineText > w then lineText = lineText:sub(1, w) end mon.write(lineText) end - logsStartY = upcomingStartY + visibleCount + 1 + logsStartY = math.max(logsStartY, upcomingStartY + visibleCount + 1) else mon.setTextColor(COLORS.WARNING) - if upcomingStartY + 1 <= h then - mon.setCursorPos(1, upcomingStartY + 1) + local msgY = upcomingStartY + 1 + if State.debugUpcoming then msgY = upcomingStartY + 2 end + if msgY <= h then + mon.setCursorPos(1, msgY) mon.write("NONE / WAITING DATA") - logsStartY = upcomingStartY + 2 + logsStartY = math.max(logsStartY, msgY + 1) else - logsStartY = upcomingStartY + 1 + logsStartY = math.max(logsStartY, msgY) end end end @@ -2281,11 +2299,24 @@ function Main.loop() while true do local now = os.epoch("utc") local newUpcoming = {} + local dbg = { + hasBR = Peripherals.blockReader ~= nil, + hasCT = Peripherals.createTarget ~= nil, + ok = false, + trainStopsCount = 0 + } -- Check Block Reader (Advanced Peripherals) first for precise ETA and Delay if Peripherals.blockReader then local ok, data = pcall(Peripherals.blockReader.getBlockData) + dbg.ok = ok and true or false if ok and data and data.TrainStops then + local c = 0 + for _ in ipairs(data.TrainStops) do c = c + 1 end + if c == 0 then + 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 if not State.lastRefreshed or State.lastRefreshed ~= data.LastRefreshed then State.lastRefreshed = data.LastRefreshed @@ -2432,6 +2463,7 @@ function Main.loop() -- Update Upcoming Trains globally for the monitor State.upcomingTrains = newUpcoming + State.debugUpcoming = dbg if not Peripherals.station then State.currentTrain = nil