Daniel_I_Am

baseControl_03.lua

Mar 9th, 2018
120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 12.25 KB | None | 0 0
  1. --pastebin get Jn1LvVhv /home/baseControl.lua -f; /home/baseControl.lua
  2. do --import
  3.   component = require("component")
  4.   term = require("term")
  5.   event = require("event")
  6.   sides = require("sides")
  7.   computer = require("computer")
  8.   os = require("os")
  9.   keyboard = require("keyboard")
  10.   shell = require("shell")
  11.   BA = require("ButtonAPI")
  12. end
  13.  
  14. do --configure from import
  15.   internet = require("component").internet
  16.   screen = component.screen
  17.   gpu = component.gpu
  18. end
  19. ---------- TABLES -----------
  20. colors = { black = 0x000000, white = 0xf8f8ff, blue = 0x0000ff, lightGray = 0xd9d9d9, red = 0xff0000,
  21. purple = 0x9b30ff, carrot = 0xffa500, magenta = 0xcd00cd, lightBlue = 0x87cefa, yellow = 0xffff00,
  22. lime = 0x32cd32, pink = 0xffc0cb, gray = 0x696969, brown = 0x8b4500, green = 0x006400, cyan = 0x008b8b,
  23. olive = 0x6b8e23, gold = 0x8b6914, orangered = 0xdb4e02, diamond = 0x0fa7c7,crimson = 0xaf002a,fuchsia = 0xfd3f92,
  24. folly = 0xff004f, frenchBlue = 0x0072bb, lilac = 0x86608e, flax = 0xeedc82, darkGray = 0x563c5c,
  25. englishGreen = 0x1b4d3e, eggplant = 0x614051, deepPink  = 0xff1493, ruby = 0x843f5b, orange = 0xf5c71a,
  26. lemon = 0xffd300, darkBlue = 0x002e63, bitterLime = 0xbfff00 } --doesn't this look very fucking fancy :3
  27.  
  28. listOfComponents = {
  29. --{id, displayName, redstoneOutputSide, isInvertedSignal},
  30. }
  31.  
  32. oddList = {}
  33. evenList = {}
  34. status = {}
  35.  
  36. ------- VARIABLES -------------
  37.  
  38. Border_bg = colors.diamond
  39. Default_bg = colors.gray
  40. text_col = colors.blue
  41. status_col = colors.black
  42. barBack = colors.black
  43. barFill = colors.white
  44. header = colors.orange
  45.  
  46. buttonXOff = 10
  47. buttonYOff = 10
  48. buttonWidth = 21
  49. buttonHeight = 3
  50. buttonSpacingX = 5
  51. buttonSpacingY = 3
  52. buttonColorButtonOn = colors.lime
  53. buttonColorButtonOff = colors.red
  54. buttonColorText = colors.black
  55. buttonsColumn = 3
  56.  
  57. -------- FUNCTIONS --------------
  58.  
  59. args, options = shell.parse(...) --grav supplied arguments and option, args are not used
  60.  
  61. function init() --initialization
  62.   local canPass = true --if canPass == false then stop the program (end)
  63.   for i = 1, #listOfComponents do --loop through components
  64.     if #listOfComponents[i] < 4 then --to check if we had enough args supplied
  65.       canPass = false --if not, then we say we cannot execute the program
  66.       io.stderr:write("Component array number " .. i .. " is missing arguments, 4 expected, received only " .. #listOfComponents[i] .. ".\n") --debug
  67.     end
  68.     local comp, _ = component.get(listOfComponents[i][1]) --also check wether the components exists
  69.     local type = "nil" --down here
  70.     if comp ~= nil then type = component.proxy(comp).type end --well, more like down here
  71.     if type ~= "redstone" then --if it is not the right type
  72.       canPass = false --then we do not allow execution
  73.       io.stderr:write("Components array number " .. i .. " is not supplied with valid ID. Received block of type " .. type .. "\n") --debug
  74.     end
  75.   end
  76.   os.sleep(1)
  77.   if not canPass then os.exit() end --check wether we allowed the program to run based on init checks
  78.   w, h = gpu.getResolution() --otherwise get global vars for resolution
  79.   for i = 1, #listOfComponents do --go through the list of components
  80.     table.insert(oddList, i * 2 - 1) --and do something, I swear it *is* indeed used for something
  81.     table.insert(evenList, i * 2) --but I cannot remember for the life of me why this is
  82.     table.insert(status, true) --really necessary
  83.   end
  84.   createButtons(listOfComponents) --of course we create the buttons
  85.   if options.c then --check supplied options, only -c right now
  86.     clearLog() --clear the log and reset to default
  87.   end
  88.   fileWrite("/etc/baseControl/logs/latest.log", getTime() .. ": " .. "Base Control initialized", false) --debug
  89.   screen.setTouchModeInverted(true) --set prefered touch mode
  90.   for i = 1, #listOfComponents do
  91.     status[i] = component.proxy(listOfComponents[i][1]).getOutput(listOfComponents[i][3]) > 0
  92.     if listOfComponents[i][4] then status[i] = not status[i] end
  93.   end
  94. end
  95.  
  96. function clearLog() --this clears log
  97.   os.execute("md /etc/baseControl/logs/") --makes sure the folder /etc/baseControl/logs/ exists
  98.   os.execute("cp /etc/baseControl/logs/latest.log /etc/baseControl/logs/" .. getTime():gsub(" ", "-"):gsub(":", "-") .. ".log") --copies the current log with timestamp over
  99.   os.execute("echo \"Base Control Log:\" > /etc/baseControl/logs/latest.log") --makes new log
  100. end
  101.  
  102. function shutdown()
  103.   --shouldRep = true --don't need this
  104.   gpu.setForeground(0xffffff) --reset colors
  105.   gpu.setBackground(0x000000)
  106.   gpu.setResolution(gpu.maxResolution()) --reset resolution
  107.   term.clear() --reset text on screen
  108.   screen.setTouchModeInverted(false) --reset touch mode
  109.   print("You've terminated Base Control") --print debug
  110.   _, _, _, _, player = event.pull("key_up") --wait until someone releases a key (this is the only way the program can be stopped when shutdown() is called)
  111.   fileWrite("/etc/baseControl/logs/latest.log", getTime() .. ": " .. player .." terminated Base Control", false) --write their name to file
  112.   clearLog() --save the log
  113. end
  114.  
  115. function getTime() --get time, this is just a pain in the ***
  116.   page = internet.request("http://worldclockapi.com/api/jsonp/cet/now?callback=mycallback") --request page
  117.   repeat --loop
  118.   file = page.read() --file read
  119.   until file ~= "" --until we have something not empty string, this will be the time
  120.   a,b = file:find("%d+%-%d+%-%d..%d+:%d+") --I love bodging (bodging = making a temporary repair)
  121.   c = file:sub(a, b):find("T") --yeeeeaaahhhh... it's necessary
  122.   time = "[" .. file:sub(a, a + c - 2) .. " " .. file:sub(a + c, b) .. "]" --this mess
  123.   return time --return the mess
  124. end
  125.  
  126. function guiBorders(x,y,len,height,str) -- BORDER FUNC FOR GUI
  127.   gpu.setBackground(Border_bg)
  128.   gpu.fill(x,y,len,height,str)
  129.   gpu.setBackground(Default_bg)
  130. end
  131.  
  132. function fileWrite(fileLocation, str, isOverwrite)
  133.   if isOverwrite==true then mode = "w" else mode = "a" end --get mode, 'w' overwrite or 'a' append
  134.   f = io.open(tostring(fileLocation),mode) --open file
  135.   f:write(tostring(str).."\n") --write text
  136.   f:close() --close file, just good habit
  137. end
  138.  
  139. function GUI() -- SETS THE GUI LAYOUT (GRAPHICAL USER INTERFACE)
  140.   gpu.setBackground(Default_bg) --set background to Default_bg-color
  141.   term.clear() --clear to apply color everywhere
  142.   --w,  h = gpu.getResolution() --not necessary, already defined in init()
  143.   guiBorders(1,1,w,1," ") --draw borders
  144.   guiBorders(1,5,w,1," ")
  145.   for i = 1,h do
  146.     guiBorders(1,i,1,1," ")
  147.     guiBorders(w,i,1,1," ")
  148.   end
  149.   guiBorders(1,h,w,1," ")
  150.   gpu.setForeground(header)
  151.   Center(3,"--[[ Base Control ]]--") --set text
  152. end
  153.  
  154. function comma_value(n) -- credit http://richard.warburton.it
  155.   local left,num,right = string.match(n,'^([^%d]*%d)(%d*)(.-)$') --you do you, richard warburton, you do you
  156.   return left..(num:reverse():gsub('(%d%d%d)','%1.'):reverse())..right --I cannot explain this in simple comments
  157. end --at least, not yet... I will someday, would actually have to put in effort
  158.  
  159. function centerText(str, x1, x2, y, FGCol, BGCol) --this is copied from the official danAPI.lua, pretty selfexplanatory
  160.   if not component.isAvailable("gpu") then return end --safety
  161.   local w,_ = gpu.getResolution()
  162.   x1 = x1 or 1 --define undefined variables
  163.   x2 = x2 or w
  164.   y = y or 1
  165.   str = str or "text"
  166.   FGCol = FGCol or gpu.getForeground()
  167.   BGCol = BGCol or gpu.getBackground()
  168.   local prevFG = gpu.getForeground() --get previous color values, to reset to later on
  169.   local prevBG = gpu.getBackground()
  170.   local l = string.len(tostring(str)) --get length
  171.   local center = math.floor((x1+x2)/2) --get center of string
  172.   local startPos = math.ceil(center - (l-1)/2) --now figure out the starting position
  173.   gpu.setForeground(FGCol) --dothe printing
  174.   gpu.setBackground(BGCol)
  175.   gpu.set(startPos,y,str)
  176.   gpu.setForeground(prevFG) --reset colors
  177.   gpu.setBackground(prevBG)
  178. end
  179.  
  180. function Center(y, text) --the bad version of centerText()
  181.   w, h = gpu.getResolution()
  182.   term.setCursor((w-string.len(text))/2+1, y)
  183.   term.write(text)
  184. end
  185.  
  186. function createButtons(list) --create all buttons, one for on and one for off
  187.   BA.clear()
  188.   for i,v in ipairs(list) do
  189.     --These couple lines are not quite clean enough for my liking, but they do work
  190.     BA.makeButton(buttonXOff + math.floor((i-1)/3) * (buttonWidth + buttonSpacingX), buttonYOff + ((i - 1) % buttonsColumn) * (buttonHeight + buttonSpacingY), buttonWidth, buttonHeight, buttonColorButtonOn, buttonColorText, -1, -1, list[i][2])
  191.     BA.makeButton(buttonXOff + math.floor((i-1)/3) * (buttonWidth + buttonSpacingX), buttonYOff + ((i - 1) % buttonsColumn) * (buttonHeight + buttonSpacingY), buttonWidth, buttonHeight, buttonColorButtonOff, buttonColorText, -1, -1, list[i][2])
  192.   end
  193. end
  194.  
  195. function displayPower()
  196.   if not component.isAvailable("draconic_rf_storage") then return end --only continue IF there is a power ball
  197.   draco = component.draconic_rf_storage
  198.   do --read values
  199.     power = draco.getEnergyStored()
  200.     maxPower = draco.getMaxEnergyStored()
  201.     transfer = draco.getTransferPerTick()
  202.     powerPCT = math.floor(100000 * power/maxPower + 5)/1000
  203.   end
  204.   do --do stuff with values
  205.     if transfer < 0 then isNegTransfer = true else isNegTransfer = false end
  206.     if isNegTransfer then transferColor = colors.red else transferColor = colors.lime end
  207.     off = 90
  208.     if power >= 1e14 then power = tostring(power); power = power:sub(1,5) .. power:sub(-4) end
  209.     if maxPower >= 1e14 then maxPower = tostring(maxPower); maxPower = maxPower:sub(1,5) .. maxPower:sub(-4) end
  210.   end
  211.   do --the actual dislay
  212.     gpu.set(off, 6, "Power:")  
  213.     gpu.set(off, 7, "    " .. comma_value(tostring(power)) .. " / " .. comma_value(tostring(maxPower)) .. " RF (" .. powerPCT .. "%)    ")
  214.     gpu.set(off, 8, "Usage:")
  215.     temp = gpu.getForeground()
  216.     gpu.setForeground(transferColor)
  217.     gpu.set(off, 9, string.rep(" ", w - off - 1))
  218.     gpu.set(off, 9, "    " .. comma_value(tostring(transfer)) .. " RF/t")
  219.     gpu.setForeground(temp)
  220.   end
  221. end
  222.  
  223. function drawButtons()
  224.     for i = 1, #listOfComponents do
  225.     if status[i] then j = 0 else j = 1 end
  226.     BA.draw({2*i + j - 1})
  227.   end
  228. end
  229.  
  230. do --main code
  231.   gpu.setResolution(150,30) --set resolution, why is this not in GUI() or init()
  232.   init() --set base values
  233.   GUI() --make general purpose GUI
  234.  
  235.   repeat
  236.     drawButtons() --draws the correct buttons, only the ones for the right state
  237.     startTime = computer.uptime() --take time for proper timer functionality
  238.     do --execute main code
  239.       local e,id,x,y,b,p = event.pull(1,"touch") --wait for possible touch event
  240.       if e ~= nil then --if we touched e == "touch"
  241.         buttonsPressed = BA.updateAll(e,id,x,y,b,p) --check which buttons we pressed, this will be button x and x+1
  242.         buttonsPressed = {buttonsPressed[1], buttonsPressed[2]} --grab only the first two touches, so we have an array of {x, x+1}
  243.         if buttonsPressed[1] ~= nil then --check if we actually clicked a button and not nothing
  244.           fileWrite("/etc/baseControl/logs/latest.log", getTime() .. ": " .. p .. " toggled " .. listOfComponents[buttonsPressed[2]/2][2]) --debug
  245.           if status[buttonsPressed[2]/2] then --check what the status is of the button
  246.             buttonPressed = buttonsPressed[1] --if it's true then only check the on state of the button
  247.           else --else
  248.             buttonPressed = buttonsPressed[2] --only check the state of the off button
  249.           end
  250.           status[buttonsPressed[2]/2] = not status[buttonsPressed[2]/2] --toggle status of the button
  251.           if status[buttonsPressed[2]/2] then --set rs output based on status
  252.             out = 15
  253.           else
  254.             out = 0
  255.           end
  256.           if listOfComponents[buttonsPressed[2]/2][4] then out = 15 - out end --adjust based on isInvertedSignal
  257.           component.proxy(listOfComponents[buttonsPressed[2]/2][1]).setOutput(listOfComponents[buttonsPressed[2]/2][3], out) --actually do the output now
  258.         end
  259.       end
  260.     end
  261.     displayPower() --show power if we have a power ball (check in function)
  262.     repeat --make sure we actualy wait 0.5 seconds
  263.       os.sleep(0.05)
  264.     until computer.uptime() >= startTime + 0.5
  265.     shouldRep = not keyboard.isControlDown() --check if we need to stop
  266.   until shouldRep == false --if we clicked stop, stop
  267.   shutdown() --stop
  268. end
Advertisement
Add Comment
Please, Sign In to add comment