Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- settings.load()
- local track_count = settings.get("bahnhof.gleisanzahl")
- local tracks = {}
- local decoder = require("cc.audio.dfpwm").make_decoder()
- local station_link = peripheral.wrap(settings.get("bahnhof.anzeigelink"))
- station_link.setWidth(48)
- for i = 1, track_count do
- tracks[i] = {
- station_a = peripheral.wrap(settings.get("bahnhof.gleis" .. i .. ".station_a")),
- station_b = peripheral.wrap(settings.get("bahnhof.gleis" .. i .. ".station_b")),
- monitors = {},
- speaker = peripheral.wrap(settings.get("bahnhof.gleis" .. i .. ".speaker")),
- state = "empty",
- previous_state = "empty"
- }
- for j, v in ipairs(settings.get("bahnhof.gleis" .. i .. ".monitors")) do
- tracks[i].monitors[j] = peripheral.wrap(v)
- end
- end
- -- #region Helper functions
- local function string_trim(s)
- return (string.gsub(s, "^%s*(.-)%s*$", "%1"))
- end
- local function monitor_write(track_id, x_pos, y_pos, text, color)
- if color == nil then
- color = colors.white
- end
- for i, m in ipairs(tracks[track_id].monitors) do
- m.setCursorPos(x_pos, y_pos)
- m.setTextColor(color)
- m.write(text)
- end
- end
- local function monitor_clear_line(track_id, line)
- for i, m in ipairs(tracks[track_id].monitors) do
- m.setCursorPos(1, line)
- m.clearLine()
- end
- end
- -- #endregion
- -- #region Station functions
- local function read_station_link(track_id)
- local display_line = nil
- for i = 1, track_count do
- display_line = string_trim(station_link.getLine(i))
- if string.sub(display_line, -1) == tostring(track_id) then
- return display_line
- end
- end
- return nil
- end
- local function get_arrival_time(track_id)
- if tracks[track_id].station_a.isTrainImminent() or
- tracks[track_id].station_b.isTrainImminent() then
- return 0
- end
- if tracks[track_id].station_a.isTrainPresent() or
- tracks[track_id].station_b.isTrainPresent() then
- return nil
- end
- local display_line = read_station_link(track_id)
- if display_line == nil then
- return nil
- end
- if string.find(display_line, "~") then
- return 99
- elseif string.find(display_line, "min") then
- return tonumber(string.sub(display_line, 1, 3))
- elseif string.find(display_line, "s") or string.find(display_line, "now") then
- return 0
- else
- return nil
- end
- end
- local function get_train_name(track_id)
- local train_name = nil
- if tracks[track_id].station_a.isTrainPresent() then
- train_name = tracks[track_id].station_a.getTrainName()
- elseif tracks[track_id].station_b.isTrainPresent() then
- train_name = tracks[track_id].station_b.getTrainName()
- end
- if train_name == nil then
- local display_line = read_station_link(track_id)
- if display_line == nil then
- return nil
- end
- local i, _ = string.find(display_line, "BB-")
- if i == nil then
- return "UNKW"
- end
- train_name = string.sub(display_line, i, i + 6)
- end
- if #train_name ~= 7 and not string.sub(train_name, 1, 3) == "BB-" then
- return "UNKW"
- end
- return string.sub(train_name, 4, 7)
- end
- local function get_destination(track_id)
- local display_line = read_station_link(track_id)
- if display_line == nil then
- return nil
- end
- local i, j = string.find(display_line, "(^).+($)")
- if i == nil then
- return nil
- end
- return string.sub(display_line, i + 1, j - 1)
- end
- local function get_station_infos(track_id)
- local station_info = {
- arrival_time = get_arrival_time(track_id),
- train_name = get_train_name(track_id),
- destination = get_destination(track_id)
- }
- return station_info
- end
- -- #endregion
- -- #region Display functions
- local function init_displays()
- print("Initializing displays")
- for i = 1, track_count do
- for _, m in ipairs(tracks[i].monitors) do
- m.clear()
- end
- monitor_write(i, 1, 1, "Gleis " .. i)
- end
- end
- local function print_clock(track_id)
- local time = textutils.formatTime(os.time(), true)
- if #time == 4 then
- time = "0" .. time
- end
- monitor_write(track_id, 14, 1, time)
- end
- local function print_train_name(track_id, train_name)
- if train_name == nil then
- monitor_clear_line(track_id, 3)
- else
- monitor_write(track_id, 2, 3, train_name, colors.cyan)
- end
- end
- local function print_arrival_time(track_id, arrival_time)
- monitor_clear_line(track_id, 4)
- if arrival_time == nil then
- return
- elseif tracks[track_id].state == "incoming" then
- monitor_write(track_id, 2, 4, " Zug faehrt ein ", colors.yellow)
- elseif arrival_time > 0 then
- monitor_write(track_id, 2, 4, "Ankunft: ")
- if arrival_time >= 99 then
- monitor_write(track_id, 11, 4, ">10 min", colors.lightGray)
- else
- local time_str = tostring(arrival_time)
- monitor_write(track_id, 14 - #time_str, 4, time_str .. " min")
- end
- end
- end
- local function print_destination(track_id, destination)
- monitor_write(track_id, 7, 3, " ")
- if destination == nil then
- return
- end
- local i, j = string.find(destination, "via ")
- local via = nil
- if i == nil then
- destination = string.sub(destination, 1, 11)
- else
- via = string.sub(destination, i, j + 1 + 11)
- if i > 11 then
- destination = string.sub(destination, 1, 11)
- else
- destination = string.sub(destination, 1, i - 1)
- end
- end
- if tracks[track_id].station_a.isTrainPresent() or
- tracks[track_id].station_b.isTrainPresent() then
- if destination == "FINAL_DEST" then
- monitor_write(track_id, 2, 4, "nicht einsteigen", colors.red)
- return
- end
- if via == nil then
- monitor_write(track_id, 2, 4, "bitte einsteigen", colors.green)
- else
- monitor_write(track_id, 3, 4, via)
- end
- end
- if destination ~= "FINAL_DEST" then
- monitor_write(track_id, 7, 3, destination)
- end
- end
- -- #endregion
- -- #region Speaker functions
- local function play_chime(track_id)
- tracks[track_id].speaker.playNote("pling", 3, 10)
- sleep(0.3)
- tracks[track_id].speaker.playNote("pling", 3, 6)
- sleep(0.3)
- tracks[track_id].speaker.playNote("pling", 3, 1)
- end
- local function play_text(track_id, text)
- play_chime(track_id)
- sleep(0.3)
- local url = "https://music.madefor.cc/tts?text=" .. textutils.urlEncode(text) .. "&voice=de"
- local response, err = http.get { url = url, binary = true }
- if not response then error(err, 0) end
- while true do
- local chunk = response.read(16 * 1024)
- if not chunk then break end
- local buffer = decoder(chunk)
- while not tracks[track_id].speaker.playAudio(buffer, 3) do
- os.pullEvent("speaker_audio_empty")
- end
- end
- sleep(3)
- end
- local function play_announcement(track_id, station_info)
- if tracks[track_id].state == "incoming" then
- if station_info.destination == nil or station_info.train_name == nil or station_info.train_name =="UNKW" then
- play_text(track_id, "Vorsicht am Gleis ".. track_id ..". Ein Zug faehrt ein")
- elseif station_info.destination == "FINAL_DEST" then
- play_text(track_id, "Vorsicht am Gleis ".. track_id ..". Der einfahrende Zug endet hier. Bitte nicht einsteigen!")
- else
- local i, j = string.find(station_info.destination, "via ")
- if i == nil then
- play_text(track_id, "Gleis ".. track_id ..". Einfahrt, ".. station_info.train_name .." Richtung ".. station_info.destination)
- else
- local via = string.sub(station_info.destination, j+1, #station_info.destination)
- local destination = string.sub(station_info.destination, 1, i-1)
- play_text(track_id, "Gleis ".. track_id ..". Einfahrt, ".. station_info.train_name .." Richtung ".. destination .. ", ueber ".. via)
- end
- end
- elseif tracks[track_id].state == "final" then
- play_text(track_id, "Der eingfahrene Zug auf Gleis " .. track_id .. " endet hier. Bitte alle aussteigen!")
- elseif tracks[track_id].state == "arrived" then
- local i, j = string.find(station_info.destination, "via ")
- if i == nil then
- play_text(track_id, "Eingefahrener Zug auf Gleis ".. track_id ..": ".. station_info.train_name .." Richtung ".. station_info.destination)
- else
- local via = string.sub(station_info.destination, j+1, #station_info.destination)
- local destination = string.sub(station_info.destination, 1, i-1)
- play_text(track_id, "Eingefahrener Zug auf Gleis ".. track_id ..": ".. station_info.train_name .." Richtung ".. destination .. ", ueber ".. via)
- end
- elseif tracks[track_id].state == "boarding" then
- local i, j = string.find(station_info.destination, "via ")
- if i == nil then
- play_text(track_id, "Gleis ".. track_id .." steht: ".. station_info.train_name .." Richtung ".. station_info.destination ..". Bitte einsteigen!")
- else
- local via = string.sub(station_info.destination, j+1, #station_info.destination)
- local destination = string.sub(station_info.destination, 1, i-1)
- play_text(track_id, "Gleis ".. track_id .." steht: ".. station_info.train_name .." Richtung ".. destination .. ", ueber ".. via ..". Bitte einsteigen!")
- end
- end
- end
- -- #endregion
- local function update_displays()
- while true do
- for i = 1, track_count do
- monitor_write(i, 14, 1, textutils.formatTime(os.time(), true))
- local station_info = get_station_infos(i)
- print_clock(i)
- print_train_name(i, station_info.train_name)
- print_arrival_time(i, station_info.arrival_time)
- print_destination(i, station_info.destination)
- end
- sleep(1)
- end
- end
- local function update_states()
- while true do
- for i = 1, track_count do
- local station_info = get_station_infos(i)
- tracks[i].previous_state = tracks[i].state
- if tracks[i].station_a.isTrainPresent() or
- tracks[i].station_b.isTrainPresent() then
- if station_info.destination == nil then
- tracks[i].state = "present"
- elseif station_info.destination == "FINAL_DEST" then
- tracks[i].state = "final"
- elseif tracks[i].previous_state == "incoming" or tracks[i].previous_state == "arrived" then
- tracks[i].state = "arrived"
- else
- tracks[i].state = "boarding"
- end
- elseif tracks[i].previous_state == "present" or tracks[i].previous_state == "final" or tracks[i].previous_state == "arrived" or tracks[i].previous_state == "boarding" then
- tracks[i].state = "leaving"
- elseif station_info.arrival_time ~= nil and station_info.arrival_time < 1 and (tracks[i].previous_state == "empty" or tracks[i].previous_state == "incoming") then
- tracks[i].state = "incoming"
- else
- tracks[i].state = "empty"
- end
- print("Track " .. i .. " state: " .. tracks[i].state)
- end
- sleep(2.5)
- end
- end
- local function play_announcements()
- while true do
- for i = 1, track_count do
- if tracks[i].previous_state ~= tracks[i].state then
- print("Playing announcement for track " .. i)
- local station_info = get_station_infos(i)
- play_announcement(i, station_info)
- end
- end
- sleep(1)
- end
- end
- print("Train Station Control")
- init_displays()
- parallel.waitForAll(update_states, update_displays, play_announcements)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement