Advertisement
fatboychummy

Wolfe's Mekanism Induction Matrix Monitor but the text is center-aligned

Jun 18th, 2023
1,177
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.26 KB | None | 0 0
  1. --[[
  2.   Wolfe's Mekanism Induction Matrix Monitor
  3.   Usage: Put computer with code near an Induction Port and a monitor (2x3 array should work fine) and run.
  4.   Configuration: You can add a file called "config" with the options below, or append them to the command when running it via terminal:
  5.     energy_type = 'FE' -- Energy type you want to use
  6.     update_frequency = 1 -- Update frequency, in seconds
  7.     text_scale = 1 -- The text scale on the monitor, use 0.5 if you want to run on less displays
  8.     side_monitor = 'right' -- Hardcodes which side the monitor should be, defaults to auto-detection
  9.     side_inductor = 'back' -- Hardcodes which side the Induction Port should be, defaults to auto-detection
  10.  
  11.   Edited to center-align the text.
  12. ]]
  13.  
  14. --
  15. -- Usage: Put computer near an Induction Port and a monitor , set the sides below and run.
  16.  
  17. -- Default settings
  18. options = {
  19.   energy_type = 'FE',
  20.   update_frequency = 1,
  21.   text_scale = 1,
  22. }
  23.  
  24. -- Loads custom options from file (if available)
  25. if fs.exists('config') then
  26.   -- Opens the file for reading
  27.   local handle = fs.open('config')
  28.  
  29.   -- Reads configs
  30.   raw_options = {}
  31.   local line = handle.readLine()
  32.   while line do
  33.     table.insert(raw_options, line)
  34.     line = handle.readLine()
  35.   end
  36.  
  37.   -- Sets custom options
  38.   custom_options = string.format('{%s}', table.concat(raw_options, '\n,'))
  39.  
  40.   -- Closes the handle properly
  41.   handle.close()
  42. end
  43.  
  44. -- Gets custom settings via arguments
  45. args = {...}
  46. if args and #args > 0 then
  47.   -- Parses custom settings from args
  48.   custom_options = string.format('{%s}', table.concat(args, '\n,'))
  49. end
  50.  
  51. -- Detects custom options
  52. if custom_options then
  53.   -- Debug only
  54.   print('Running with custom options:')
  55.  
  56.   -- Makes sure we're dealing with a table to prevent code injection
  57.   if '{' == custom_options:sub(1, 1) then
  58.     -- Parses the object
  59.     custom_options, err = loadstring(string.format('return %s', custom_options))
  60.  
  61.     -- Handles invalid object
  62.     if not custom_options then
  63.       print('Invalid options:')
  64.       print(err)
  65.     else
  66.       -- Replaces settings
  67.       for k, v in pairs(custom_options()) do
  68.         print(string.format('%s = %s', k, v))
  69.         options[k] = v
  70.       end
  71.     end
  72.   end
  73. end
  74.  
  75. -- Auto-detects sides
  76. for _, side in pairs(peripheral.getNames()) do
  77.   -- Auto-detects monitor
  78.   if 'monitor' == peripheral.getType(side) and (not options.side_monitor) then
  79.     options.side_monitor = side
  80.   end
  81.  
  82.   -- Auto-detects Induction Port
  83.   if 'inductionPort' == peripheral.getType(side) and (not options.side_inductor) then
  84.     options.side_inductor = side
  85.   end
  86. end
  87.  
  88. -- Connects to Peripherals
  89. monitor = peripheral.wrap(options.side_monitor)
  90.  
  91. -- Queues a new print command to be sent
  92. buffer = {}
  93. function queue (text)
  94.   table.insert(buffer, text)
  95. end
  96.  
  97. -- Queues a new print command with string.format
  98. function queuef (fmt, ...)
  99.   queue(string.format(fmt, ...))
  100. end
  101.  
  102. -- Flushes (prints) buffer content
  103. function queue_flush ()
  104.   -- Clears terminal
  105.   term.clear()
  106.   term.setCursorPos(1, 1)
  107.  
  108.   -- Writes new data, center aligned
  109.   local w, h = term.getSize()
  110.   local y_offset = math.ceil(h / 2 - #buffer / 2) - 1
  111.   for y, line in ipairs(buffer) do
  112.     term.setCursorPos(
  113.       math.ceil(w / 2 - #line / 2),
  114.       y + y_offset
  115.     )
  116.     term.write(line)
  117.   end
  118.   buffer = {}
  119. end
  120.  
  121. -- Formats time
  122. function time (secs)
  123.   -- Prepare value
  124.   secs = math.floor(secs)
  125.  
  126.   -- Days
  127.   local weeks = math.floor(secs / 604800)
  128.   secs = secs - (604800 * weeks)
  129.  
  130.   -- Days
  131.   local days = math.floor(secs / 86400)
  132.   secs = secs - (86400 * days)
  133.  
  134.   -- Hours
  135.   local hours = math.floor(secs / 3600)
  136.   secs = secs - (3600 * hours)
  137.  
  138.   -- Minutes
  139.   local mins = math.floor(secs / 60)
  140.   secs = secs - (60 * mins)
  141.  
  142.   -- If we have more than 72h worth of storage, switch to week, day, hour format
  143.   if weeks > 0 then
  144.     return string.format('%dwk %dd %dh', weeks, days, hours)
  145.   elseif days >= 3 then
  146.     return string.format('%dd %dh', days, hours)
  147.   end
  148.  
  149.   -- Formatting to have trailing zeros on H:MM:SS
  150.   return string.format('%d:%02d:%02d', hours, mins, secs)
  151. end
  152.  
  153. -- Rounds number
  154. function rnd (val, dec)
  155.   local X = math.pow(10, dec)
  156.   return math.floor(val * X) / X
  157. end
  158.  
  159. -- Converts to percentage
  160. function pct (val, dec)
  161.   return rnd(100 * val, dec or 1) .. '%'
  162. end
  163.  
  164. -- Converts to readable power
  165. function pwr (val, dec)
  166.   local pre = ''
  167.   local suf = ''
  168.  
  169.   local is_neg = false
  170.   if val < 0 then
  171.     pre = '-'
  172.     is_neg = true
  173.     val = -val
  174.   end
  175.  
  176.   val = energy_function(val)
  177.  
  178.   if val > 1000 then
  179.     suf = 'k'
  180.     val = val / 1000
  181.   end
  182.  
  183.   if val > 1000 then
  184.     suf = 'M'
  185.     val = val / 1000
  186.   end
  187.  
  188.   if val > 1000 then
  189.     suf = 'G'
  190.     val = val / 1000
  191.   end
  192.  
  193.   if val > 1000 then
  194.     suf = 'T'
  195.     val = val / 1000
  196.   end
  197.  
  198.   return string.format('%s%s%s%s', pre, rnd(val, dec or 1), suf, energy_type)
  199. end
  200.  
  201. -- Checks induction port
  202. function check_connection ()
  203.   return inductor and inductor.getEnergy and inductor.getLastInput
  204. end
  205.  
  206. -- Detects energy type, sets energy function
  207. energy_type = options.energy_type
  208. energy_function = mekanismEnergyHelper[string.format('joulesTo%s', energy_type)]
  209.  
  210. -- Function not found, use default Joules and a stub
  211. if not energy_function then
  212.   energy_type = 'J'
  213.   energy_function = function (val) return val end
  214. end
  215.  
  216. -- Starts monitor
  217. term.redirect(monitor)
  218. monitor.setTextScale(options.text_scale)
  219.  
  220. -- Checks if Inductor Port is missing or multiblock not ready
  221. inductor = peripheral.wrap(options.side_inductor)
  222. while not check_connection() do
  223.   -- Writes error message
  224.   queue('Ind.Port not found')
  225.   queue('Check connections.')
  226.   queue('Waiting...')
  227.  
  228.   -- Prints
  229.   queue_flush()
  230.  
  231.   -- Wait for next update
  232.   os.sleep(options.update_frequency)
  233.  
  234.   -- Tries to detect port
  235.   if not options.side_inductor then
  236.     for _, side in pairs(peripheral.getNames()) do
  237.       -- Tries to find an induction port
  238.       if 'inductionPort' == peripheral.getType(side) then
  239.         options.side_inductor = side
  240.         inductor = peripheral.wrap(options.side_inductor)
  241.       end
  242.     end
  243.   else
  244.     -- Try again on pre-set port
  245.     inductor = peripheral.wrap(options.side_inductor)
  246.   end
  247. end
  248.  
  249. -- Initializes balance
  250. balance = inductor.getEnergy()
  251. while true do
  252.   local status, err = pcall(function ()
  253.     -- Main script
  254.     queue('Ind.Matrix Monitor')
  255.     queue('------------------')
  256.     queue('')
  257.     queuef('Power : %s', pwr(inductor.getEnergy()))
  258.     queuef('Limit : %s', pwr(inductor.getMaxEnergy()))
  259.     queuef('Charge: %s', pct(inductor.getEnergyFilledPercentage()))
  260.     queue('')
  261.     queuef('Input : %s', pwr(inductor.getLastInput()))
  262.     queuef('Output: %s', pwr(inductor.getLastOutput()))
  263.     queuef('Max IO: %s/t', pwr(inductor.getTransferCap()))
  264.     queue('')
  265.    
  266.     -- Power balance per second
  267.     local balance_last = balance
  268.     balance = inductor.getEnergy()
  269.     local balance_change = (balance - balance_last) / options.update_frequency
  270.    
  271.     -- If we have negative value here, we'll save a character by removing the space so it fits same line
  272.     if balance_change < 0 then
  273.       queuef('Change:%s/s', pwr(balance_change))
  274.     else
  275.       queuef('Change: %s/s', pwr(balance_change))
  276.     end
  277.  
  278.     -- Status (charged/depleted in)
  279.     queue('Status:')
  280.     if balance_change > 0 then
  281.       -- Charging
  282.       local remaining_charge = inductor.getMaxEnergy() - inductor.getEnergy()
  283.       local seconds_remaining = remaining_charge / balance_change
  284.       queuef('Charg. %s', time(seconds_remaining))
  285.     elseif balance_change < 0 then
  286.       -- Discharging
  287.       local remaining_charge = inductor.getEnergy()
  288.       local seconds_remaining = remaining_charge / -balance_change
  289.       queuef('Disch. %s', time(seconds_remaining))
  290.     else
  291.       -- No changes, so we won't be charged or depleted, rare.
  292.       queue('Idle')
  293.     end
  294.   end)
  295.  
  296.   -- Checks for errors (might be disconnected)
  297.   if not status then
  298.     -- Clears buffer first
  299.     buffer = {}
  300.  
  301.     -- Shows error message
  302.     queue('Error reading data')
  303.     queue('Check connections.')
  304.     queue('------------------')
  305.     queue(err)
  306.   end
  307.  
  308.   -- Prints
  309.   queue_flush()
  310.  
  311.   -- Wait for next update
  312.   os.sleep(options.update_frequency)
  313. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement