osmarks

ARR Controller

Feb 28th, 2022 (edited)
360
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. local config = dofile "config.lua"
  2.  
  3. local function spudnet()
  4.     if not http or not http.websocket then return "Websockets do not actually exist on this platform" end
  5.    
  6.     local ws
  7.  
  8.     local function send_packet(msg)
  9.         ws.send(textutils.serialiseJSON(msg))
  10.     end
  11.  
  12.     local function send(data)
  13.         send_packet { type = "send", channel = "comm:arr", data = data }
  14.     end
  15.  
  16.     local function connect()
  17.         if ws then ws.close() end
  18.         ws, err = http.websocket "wss://spudnet.osmarks.net/v4?enc=json"
  19.         if not ws then print("websocket failure %s", err) return false end
  20.         ws.url = "wss://spudnet.osmarks.net/v4?enc=json"
  21.  
  22.         send_packet { type = "identify", implementation = "ARR control unit", key = settings.get "spudnet_key" }
  23.         send_packet { type = "set_channels", channels = { "comm:arr" } }
  24.  
  25.         print("websocket connected")
  26.  
  27.         return true
  28.     end
  29.    
  30.     local function try_connect_loop()
  31.         while not connect() do
  32.             sleep(0.5)
  33.         end
  34.     end
  35.    
  36.     try_connect_loop()
  37.  
  38.     local function recv()
  39.         while true do
  40.             local e, u, x = os.pullEvent "websocket_message"
  41.             if u == ws.url then return textutils.unserialiseJSON(x) end
  42.         end
  43.     end
  44.    
  45.     local ping_timeout_timer = nil
  46.  
  47.     local function ping_timer()
  48.         while true do
  49.             local _, t = os.pullEvent "timer"
  50.             if t == ping_timeout_timer and ping_timeout_timer then
  51.                 -- 15 seconds since last ping, we probably got disconnected
  52.                 print "SPUDNET timed out, attempting reconnect"
  53.                 try_connect_loop()
  54.             end
  55.         end
  56.     end
  57.    
  58.     local function main()
  59.         while true do
  60.             local packet = recv()
  61.             if packet.type == "ping" then
  62.                 send_packet { type = "pong", seq = packet.seq }
  63.                 if ping_timeout_timer then os.cancelTimer(ping_timeout_timer) end
  64.                 ping_timeout_timer = os.startTimer(15)
  65.             elseif packet.type == "error" then
  66.                 print("SPUDNET error", packet["for"], packet.error, packet.detail, textutils.serialise(packet))
  67.             elseif packet.type == "message" then
  68.                 os.queueEvent("spudnet_message", packet.data)
  69.             end
  70.         end
  71.     end
  72.  
  73.     return send, function() parallel.waitForAll(ping_timer, main) end
  74. end
  75.  
  76. local spudnet_send, spudnet_handler = spudnet()
  77.  
  78. local switches = {}
  79. local sweep_timer = os.startTimer(1)
  80. local function main()
  81.     while true do
  82.         local ev = {os.pullEvent()}
  83.         if ev[1] == "spudnet_message" then
  84.             local data = ev[2]
  85.             if data.type == "sw_ping" then
  86.                 data.timer = timer
  87.                 data.last_ping = os.epoch "utc"
  88.                 switches[data.id] = data
  89.                 print(data.id)
  90.                 spudnet_send { type = "sw_cmd", cmd = "set", lamp = (os.clock() % 16) * 2048 }
  91.             end
  92.         elseif ev[1] == "timer" then
  93.             if ev[2] == sweep_timer then
  94.                 local now = os.epoch "utc"
  95.                 for id, switch in pairs(switches) do
  96.                     if now - switch.last_ping >= 2000 then
  97.                         print(switch, "antimemeticized")
  98.                         switches[id] = nil
  99.                     end
  100.                 end
  101.                 sweep_timer = os.startTimer(1)
  102.             end
  103.         end
  104.     end
  105. end
  106.  
  107. parallel.waitForAll(spudnet_handler, main)
Add Comment
Please, Sign In to add comment