Advertisement
HandieAndy

IR_Auto_Switch

Oct 4th, 2019
2,764
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 6.11 KB | None | 0 0
  1. local event = require("event")
  2. local serial = require("serialization")
  3. local component = require("component")
  4. local fs = require("filesystem")
  5. local keyboard = require("keyboard")
  6.  
  7. -- The name of the file which holds information about the switches.
  8. local SWITCH_DEFINITION_FILE = "/home/switch.tbl"
  9. -- The table of switch information, that is loaded from the above file on startup.
  10. local switches = nil
  11.  
  12. local RUNNING = true
  13.  
  14. -- Loads the switch definition from a serialized table.
  15. local function loadSwitchDefinitionFromFile(filename)
  16.   local file = io.open(filename, "r")
  17.   if file == nil then
  18.     io.stderr:write("Could not open file "..filename.." for reading.\n")
  19.     return nil
  20.   end
  21.   local tbl = serial.unserialize(file:read("*a"))
  22.   file:close()
  23.   return tbl
  24. end
  25.  
  26. -- Gets a component address from the user.
  27. local function inputComponentAddress()
  28.   local address = nil
  29.   repeat
  30.     address = io.read()
  31.     if address == nil or #address ~= 36 then
  32.       print("Invalid component address. Please enter a 36-character string.")
  33.     end
  34.   until address ~= nil and #address == 36
  35.   return address
  36. end
  37.  
  38. -- Gets switch information from the user, and saves it to the file.
  39. local function initSwitchDefinitionFile(filename)
  40.   print("How many switches should this system control?")
  41.   local switchCount = nil
  42.   repeat
  43.     switchCount = tonumber(io.read())
  44.     if switchCount == nil or switchCount <= 0 then
  45.       print("Invalid number of switches given. Please enter a positive number.")
  46.     end
  47.   until switchCount ~= nil and switchCount > 0
  48.  
  49.   print("You will now enter some information about each switch.")
  50.   local tentative_switches = {}
  51.   for i=1, switchCount do
  52.     print("Switch "..i..":")
  53.    
  54.     print("What is the address of the detector augment before this switch?")
  55.     local detector_address = inputComponentAddress()
  56.     print("What is the address of the redstone component that controls this switch?")
  57.     local rs_address = inputComponentAddress()
  58.    
  59.     print("What branch is does this switch direct traffic to when activated?")
  60.     local switch_to = nil
  61.     repeat
  62.       switch_to = io.read()
  63.     until switch_to ~= nil
  64.    
  65.     print("In summary, this switch has the following information:")
  66.     print("  Detector: \""..detector_address.."\"")
  67.     print("  Redstone I/O: \""..rs_address.."\"")
  68.     print("  Switches when locomotive's tag contains: \""..switch_to.."\"")
  69.     print("Is this information correct? [y/n]")
  70.     local choice = io.read()
  71.    
  72.     if choice == "y" or choice == "yes" then
  73.       tentative_switches[i] = {
  74.         detector_address = detector_address,
  75.         rs_address = rs_address,
  76.         switch_to = switch_to
  77.       }
  78.     else
  79.       i = i - 1
  80.     end
  81.   end
  82.   print("Saving this switch definition to "..filename..".")
  83.   local f = io.open(filename, "w")
  84.   if f == nil then
  85.     io.stderr:write("Could not open file "..filename.." for writing.\n")
  86.     return nil
  87.   end
  88.   f:write(serial.serialize(tentative_switches))
  89.   f:close()
  90.   return tentative_switches
  91. end
  92.  
  93. -- Sets the output of all switches to 0, to reset the system.
  94. local function resetSwitches(switches)
  95.   for index, switch in pairs(switches) do
  96.     local redstone = component.proxy(switch.rs_address)
  97.     redstone.setOutput({0, 0, 0, 0, 0, 0})
  98.   end
  99. end
  100.  
  101. -- What to do when a train runs over a detector, just before it reaches the switch.
  102. local function onDetectorTriggered(detector_address, stock_uuid)
  103.   local this_switch = nil
  104.   for index, switch in pairs(switches) do
  105.     if switch.detector_address == detector_address then
  106.       this_switch = switch
  107.     end
  108.   end
  109.   if this_switch == nil then
  110.     io.stderr:write("Fatal error: Could not find a switch that has a detector with address: "..detector_address.."\n")
  111.     return
  112.   end
  113.  
  114.   local detector = component.proxy(detector_address)
  115.   local redstone = component.proxy(this_switch.rs_address)
  116.  
  117.   local info = detector.info()
  118.   if info == nil or info.throttle == nil then
  119.     return
  120.   end
  121.  
  122.   local tag = info.tag
  123.   if tag == nil then
  124.     tag = ""
  125.   end
  126.  
  127.   print("Approaching locomotive has tag: \""..tag.."\"")
  128.   if string.find(tag, this_switch.switch_to) then
  129.     print("  Tag contains \""..this_switch.switch_to.."\", switching.")
  130.     redstone.setOutput({15, 15, 15, 15, 15, 15})
  131.   else
  132.     print("  Tag doesn't contain \""..this_switch.switch_to.."\", not switching.")
  133.     redstone.setOutput({0, 0, 0, 0, 0, 0})
  134.   end
  135. end
  136.  
  137. -- What to do when the user has typed some keys.
  138. local function onKeyDown(code)
  139.   local key = keyboard.keys[code]
  140.   if (keyboard.isControlDown()) then
  141.     if (key == "r") then
  142.       print("Resetting switches to their default positions.")
  143.       resetSwitches(switches)
  144.     elseif (key == "q") then
  145.       print("Quitting.")
  146.       RUNNING = false
  147.     end
  148.   end
  149. end
  150.  
  151. -- General purpose event handler that delegates different events to their own functions.
  152. local function handleEvents()
  153.   local event_name, p1, p2, p3, p4, p5 = event.pull()
  154.   if event_name == "ir_train_overhead" then
  155.     local component_address = p1
  156.     local augment_type = p2
  157.     local stock_uuid = p3
  158.     if augment_type == "DETECTOR" then
  159.       onDetectorTriggered(component_address, stock_uuid)
  160.     end
  161.   elseif event_name == "key_down" then
  162.     local key_code = p3
  163.     onKeyDown(key_code)
  164.   end
  165. end
  166.  
  167. -- Load the switch definitions from either a file, or from the user if it's the first time.
  168. if (fs.exists(SWITCH_DEFINITION_FILE)) then
  169.   switches = loadSwitchDefinitionFromFile(SWITCH_DEFINITION_FILE)
  170.   print("Loaded switch definition from file.")
  171. else
  172.   print("No switch definition found, please create one now.")
  173.   switches = initSwitchDefinitionFile(SWITCH_DEFINITION_FILE)
  174.   print("Loaded switch definition from user input.")
  175. end
  176.  
  177. if switches == nil then
  178.   io.stderr:write("Fatal error: Could not load switch definition from file or user input.\n")
  179.   return
  180. end
  181.  
  182. print("Resetting switches to their starting positions.")
  183. resetSwitches(switches)
  184.  
  185. print("Waiting for locomotives... Type CTRL + Q to quit, or CTRL + R to reset switches.")
  186. -- The main loop of the program.
  187. while RUNNING do
  188.   handleEvents()
  189. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement