Advertisement
Stekeblad

PowergraphMulti

Apr 9th, 2016
3,283
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 12.65 KB | None | 0 0
  1. --PowergraphMulti is made by Stekeblad 11/2017
  2.  
  3.   ------------- Configuration part ------------------
  4.  
  5.   -- Seconds between checking stored energy
  6.   -- and updating monitors (default: 5)
  7. local updateInterval = 5
  8.  
  9. -- Simple mode tries to scan for compatible storages and
  10. -- wrap the first found one and the first found monitor
  11. -- For more advanced configuration, set this to false and
  12. -- and fill the dataTable below (example follows)
  13. -- Default: true
  14. local simpleMode = true
  15.      
  16. local dataTable = {
  17.    
  18. }
  19.  
  20.   -- help for how to fill dataTable:
  21. --[[ add a comma at the end of all lines except the
  22.   last one in all tables.
  23.   "[required]" in front of a line means you need to
  24.   have it or the program won't work, rows with
  25.   "[optional]" are optional and can be left out.
  26.   The following information can be added:
  27.  
  28.   [required] monitor = the side or network name
  29.             of a monitor connected to the computer.
  30.   [required] energy = the energy storage witch
  31.             content should be displayed on the
  32.             monitor defined above.
  33.   [optional] text = a word or sentence that will
  34.             be displayed at the bottom line on the
  35.             monitor.
  36.   [optional] blitColor = Will be ignored if its
  37.             not a advanced monitor, specifies the
  38.             color of the graph, see following link
  39.             for help:
  40.             http://www.computercraft.info/wiki/Colors_(API)#Colors
  41.             allowed values are 0-9 and a-f,
  42.             defaults to 5 (green)
  43.   [optional] textSize = Sets how large the text is and
  44.             how thick the graph line is.
  45.             Needs to be between 0.5 and 5 and is in
  46.             steps of 0.5. eg 0.5, 1, 1.5 ... 4.5, 5
  47.             Default is 1. (5 is very large text)
  48.            
  49. local Example = {
  50.   {
  51.     monitor = "monitor_1",    <-- comma
  52.     energy = "tile_blockcapacitorbank_name_0", <--comma
  53.     text = "ME Backup",     <-- comma
  54.     blitColor = "5"       <-- no comma, last line for this monitor-battery pair
  55.     },{         <-- comma between braces, there are more monitor-battery pairs
  56.     monitor = "top",      <-- comma
  57.     energy = "back",      <-- comma
  58.     textSize = 0.5    <-- no comma, last line in this pair
  59.     }       <-- no comma, this was last pair
  60.   }         <-- closing the example table, no comma
  61.  
  62.   ]] -- (ignore this two brackets, they indicate
  63.      -- the end of this long multi-line comment)
  64.  
  65. ------------- End of configuration part --------------------
  66.  
  67. -- Dont change anything below this line
  68. -- if you not know what you are doing!
  69.  
  70. if simpleMode then
  71.   dataTable.auto = {}
  72.  
  73.   -- Scan after a monitor and wrap the first one found
  74.   -- If no monitor is found, error and exit
  75.   local mon = peripheral.find("monitor")
  76.   if not mon then
  77.     error("Could not automaticly find a monitor, connect one with a wired modem or place one touching the computer")
  78.   else
  79.     dataTable.auto.monitor = mon
  80.   end
  81.  
  82.   -- Scan for energy storage, first EnderIO
  83.   local ene = peripheral.find("tile_blockcapacitorbank_name") -- basic, normal and vibrant
  84.  
  85.   -- If not found, scan for thermal expansion cells
  86.   if not ene then
  87.     ene = peripheral.find("tile_thermalexpansion_cell_basic_name")
  88.   end
  89.  
  90.   -- ImmersiveEngineering
  91.   if not ene then
  92.     ene = peripheral.find("IE:lvCapacitor")
  93.   end
  94.   if not ene then
  95.     ene = peripheral.find("IE:mvCapacitor")
  96.   end
  97.   if not ene then
  98.     ene = peripheral.find("IE:hvCapacitor")
  99.   end
  100.  
  101.   -- Draconic Evolution
  102.   if not ene then
  103.     ene = peripheral.find("draconic_rf_storage")
  104.   end
  105.  
  106.   -- Industrial Craft 2
  107.   if not ene then
  108.     ene = peripheral.find("batbox")
  109.   end
  110.   if not ene then
  111.     ene = peripheral.find("mfe")
  112.   end
  113.   if not ene then
  114.     ene = peripheral.find("mfsu")
  115.   end
  116.  
  117.   -- Mekanism
  118.   if not ene then
  119.     ene = peripheral.find("Basic Energy Cube")
  120.   end
  121.   if not ene then
  122.     ene = peripheral.find("Advanced Energy Cube")
  123.   end
  124.   if not ene then
  125.     ene = peripheral.find("Elite Energy Cube")
  126.   end
  127.   if not ene then
  128.     ene = peripheral.find("Ultimate Energy Cube")
  129.   end
  130.   if not ene then
  131.     ene = peripheral.find("Induction Matrix")
  132.   end
  133.  
  134.   -- Big Reactors
  135.   if not ene then
  136.     ene = peripheral.find("BigReactors-Reactor")
  137.   end
  138.   if not ene then
  139.     ene = peripheral.find("BigReactors-Turbine")
  140.   end
  141.  
  142.   -- plethora (peripheral)
  143.   if not ene then
  144.     local periphs = peripheral.getNames()
  145.     for _, v in pairs(periphs) do
  146.       local periph = peripheral.wrap(v)
  147.       if (periph.getMetadata and periph.getMetadata().energy
  148.       and periph.getMetadata().energy.capacity
  149.       and periph.getMetadata().energy.stored) then
  150.         ene = periph
  151.         break
  152.       end
  153.     end
  154.   end
  155.  
  156.   -- End of scanning attempts
  157.   if ene then
  158.     dataTable.auto.energy = ene
  159.   else
  160.     print("Could not automaticly find a energy storage, check the connection or try adding it in the program code in dataTable and disable simpleMode")
  161.     print("Connected peritherals: ")
  162.     local periphs = peripheral.getNames()
  163.     for _, v in pairs(periphs) do
  164.       print(v)
  165.     end
  166.     error("Fix the above and try again")
  167.   end
  168. end
  169.  
  170.  
  171. local emptyDataTable = true
  172.  
  173. -- checks information in dataTable and sets variables
  174. -- that will be used later
  175. for rowNumber, row in pairs(dataTable) do
  176.   emptyDataTable = false
  177.   local monTest
  178.   if type(row.monitor) == "table" then monTest = row.monitor -- true if on simpleMode
  179.   else monTest = peripheral.wrap(row.monitor) end
  180.  
  181.   -- Monitor stuff
  182.   if (monTest == nil) then
  183.     error("\nCould not wrap monitor on row " .. rowNumber)
  184.   end
  185.   row.monitor = monTest
  186.  
  187.   local test = row.monitor.isColor()
  188.   if (test == nil) then
  189.     error("\n\"monitor\" on row " .. rowNumber .. " is not a monitor")
  190.   end
  191.   row.monIsColor = test
  192.  
  193.   if row.textSize then
  194.     local size = row.textSize*2
  195.     if size < 1 or size > 10 or size ~= math.floor(size) then
  196.       if row.monIsColor then term.setTextColor(colors.yellow) end
  197.       print("\nInvalid textSize for monitor on row " .. rowNumber .. ". Needs to be beween 0.5 and 5 and a multiple of 0.5")
  198.       print("Using monitor default 1")
  199.       if row.monIsColor then term.setTextColor(colors.white) end
  200.     else
  201.       row.monitor.setTextScale(row.textSize)
  202.     end
  203.   end
  204.  
  205.   if (row.text ~= nil) then row.hasText = 1
  206.   else row.hasText = 0 end
  207.  
  208.   row.x, row.y = row.monitor.getSize()
  209.   row.Y = 100/(row.y - 1 - row.hasText)
  210.   row.pointsArray = {}
  211.   row.indexPointer = 1
  212.   for i = 1, row.x do
  213.     row.pointsArray[i] = row.y - row.hasText --looks like 0% in the beginning
  214.   end
  215.  
  216.   if not row.blitColor then row.blitColor = "5"
  217.   else
  218.     local bc = row.blitColor
  219.     if not (bc == "0" or bc == "1" or bc == "2" or bc == "3"
  220.     or bc == "4" or bc == "5" or bc == "6" or bc == "7"
  221.     or bc == "8" or bc == "9" or bc == "a" or bc == "b"
  222.     or bc == "c" or bc == "d" or bc == "e" or bc == "f") then
  223.       if row.monIsColor then term.setTextColor(colors.yellow) end
  224.       print("\nInvalid blitColor for monitor on row " .. rowNumber .. ". Needs to be in quotation marks and between 0-9 or a-f")
  225.       print("Defaulting to green (5)")
  226.       if row.monIsColor then term.setTextColor(colors.white) end
  227.       row.blitColor = "5"
  228.     end
  229.   end
  230.  
  231.   if row.x < 27 then row.hideStekeblad = true -- do not print "Stekeblad's Powergraph" if it
  232.   else row.hideStekeblad = false end          -- does not fit on the monitor
  233.   if ((row.hasText == 1) and (row.x < string.len(row.text))) then
  234.     if row.monIsColor then term.setTextColor(colors.yellow) end
  235.     print("\nDefined text for monitor on row " .. rowNumber .. " does not fit on screen")
  236.     if row.monIsColor then term.setTextColor(colors.white) end
  237.   end
  238.  
  239.   --  Battery stuff
  240.   local eneTest
  241.   if type(row.energy) == "table" then eneTest = row.energy
  242.   else eneTest = peripheral.wrap(row.energy) end
  243.  
  244.   if (eneTest == nil) then
  245.     error("\nCould not wrap energy storage on row " .. rowNumber)
  246.   else
  247.     row.energy = eneTest
  248.     -- check if IC2 energy storage and if so add support for it
  249.     if (row.energy.getEUStored and row.energy.getEUCapacity) then
  250.       row.energy.getEnergyStored = row.energy.getEUStored
  251.       row.energy.getMaxEnergyStored = row.energy.getEUCapacity
  252.    
  253.     -- check if mekanism energy storage and if so add support for it
  254.     elseif (row.energy.getEnergy and row.energy.getMaxEnergy) then
  255.       row.energy.getEnergyStored = row.energy.getEnergy
  256.       row.energy.getMaxEnergyStored = row.energy.getMaxEnergy
  257.    
  258.     -- check if bigreactors reactor (can store 10 million)
  259.     elseif (row.energy.getEnergyStored and row.energy.getControlRodLevel) then    
  260.       row.energy.getMaxEnergyStored = function() return 10000000 end
  261.      
  262.     -- check for bigreactors turbine (can store 1 million)
  263.     elseif (row.energy.getEnergyStored and row.energy.getBladeEfficiency) then    
  264.       row.energy.getMaxEnergyStored = function() return 1000000 end
  265.      
  266.     -- plethora (peripheral)
  267.     elseif (row.energy.getMetadata) then
  268.         local blockMeta = row.energy.getMetadata()
  269.         if (blockMeta.energy and blockMeta.energy.stored and blockMeta.energy.capacity) then
  270.             row.energy.getEnergyStored = function() return row.energy.getMetadata().energy.stored end
  271.             row.energy.getMaxEnergyStored = function() return row.energy.getMetadata().energy.capacity end
  272.         end
  273.      
  274.     -- If the energy storage is not compatible
  275.     elseif not (row.energy.getEnergyStored and row.energy.getMaxEnergyStored) then
  276.       error("\n\"energy\" on row " .. rowNumber .. " is not a energy storage or does not support the required functions")
  277.     end
  278.     row.maxEnergy = row.energy.getMaxEnergyStored()
  279.   end
  280. end
  281.  
  282.   -- Check if dataTable is empty and tell user to add something
  283. if emptyDataTable then
  284.   if term.isColor then term.setTextColor(colors.red) end
  285.   print("\nNo monitors and energy storages added, press enter to open file for editing....")
  286.   if term.isColor then term.setTextColor(colors.white) end
  287.   read()
  288.   shell.run("edit " .. shell.getRunningProgram())
  289.   return -1
  290. end
  291.  
  292. print("\nSuccessfully wrapped all monitors and energy storages as peripherals")
  293.  
  294. -- Prints one pixel of the graph in choosen color, or white if non-advanced
  295. function blitPoint(row)
  296.   if row.monIsColor then
  297.     row.monitor.blit(row.blitColor, row.blitColor, row.blitColor) -- (advanced monitor)
  298.   else
  299.     row.monitor.blit("0", "0", "0") -- Write a white 0 on a white background (normal monitor)
  300.   end
  301. end
  302.  
  303. -- Prints the "text"-value for the storage centered at the bottom, if defined
  304. function printBottomText(row)
  305.   if row.hasText == 1 then
  306.     local strLen = string.len(row.text)
  307.     row.monitor.setCursorPos((row.x-strLen+1)/2, row.y)
  308.     row.monitor.write(row.text)
  309.   end
  310. end
  311.  
  312. -- Prints "Stekeblad's Powergraph" centered at the top of the monitor, if their is enough space
  313. function printMadeBy(row)
  314.   if row.hideStekeblad == false then
  315.     local startX = math.floor(row.x/2-13)
  316.     row.monitor.setCursorPos(startX, 1)
  317.     row.monitor.write("Stekeblad's Powergraph")
  318.   end
  319. end
  320.  
  321. -- Print how many percent of the storage is full
  322. function printPercentFull(row)
  323.   row.monitor.setCursorPos(row.x-4, 1)
  324.   row.monitor.write(row.filledPercent .. "%")
  325. end
  326.  
  327. local all = {} -- Creates a table for functions that will operate on all monitor-battery pairs
  328.  
  329. -- Read from storage and find the y-value of this point
  330. all.getNewData = function ()
  331.   for rowNumber, row in pairs(dataTable) do
  332.     local stored = row.energy.getEnergyStored()
  333.     if stored == nil then
  334.       error("\n Failed to read stored energy from storage on row " .. rowNumber)
  335.     end
  336.     row.filledPercent = math.floor((stored/row.maxEnergy)*100)
  337.     local pointY = math.floor(row.filledPercent/row.Y)
  338.     if pointY == row.y - 1 - row.hasText then pointY = pointY-1 end
  339.     row.pointsArray[row.indexPointer] = row.y - pointY - row.hasText--Else is 100% bottom of screen and top is 0%
  340.     row.indexPointer = (row.indexPointer % row.x) + 1
  341.   end
  342. end
  343.  
  344. -- Refreshes what you see on the monitors
  345. all.updateView = function ()
  346.   for rowNumber, row in pairs(dataTable) do
  347.     local ptr = row.indexPointer
  348.     local Xi = 1
  349.     row.monitor.clear()
  350.     printPercentFull(row)
  351.     printMadeBy(row)
  352.     if row.hasText then printBottomText(row) end
  353.     row.monitor.setCursorPos(Xi, row.pointsArray[ptr])
  354.     blitPoint(row) -- blit one character, based on if its a advanced or normal monitor
  355.     Xi = (Xi % row.x) + 1
  356.     ptr = (ptr % row.x) + 1
  357.     while (ptr ~= row.indexPointer) do
  358.       row.monitor.setCursorPos(Xi, row.pointsArray[ptr])
  359.       blitPoint(row)
  360.       Xi = (Xi % row.x) + 1
  361.       ptr = (ptr % row.x) + 1
  362.     end
  363.   end
  364. end
  365.  
  366. --Main program loop
  367. while true do
  368.   all.getNewData()
  369.   all.updateView()
  370.   sleep(updateInterval)
  371. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement