AVTMC

Untitled

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