Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- Wolfe's Mekanism Induction Matrix Monitor
- Usage: Put computer with code near an Induction Port and a monitor (2x3 array should work fine) and run.
- Configuration: You can add a file called "config" with the options below, or append them to the command when running it via terminal:
- energy_type = 'FE' -- Energy type you want to use
- update_frequency = 1 -- Update frequency, in seconds
- text_scale = 1 -- The text scale on the monitor, use 0.5 if you want to run on less displays
- side_monitor = 'right' -- Hardcodes which side the monitor should be, defaults to auto-detection
- side_inductor = 'back' -- Hardcodes which side the Induction Port should be, defaults to auto-detection
- Edited to center-align the text.
- ]]
- --
- -- Usage: Put computer near an Induction Port and a monitor , set the sides below and run.
- -- Default settings
- options = {
- energy_type = 'FE',
- update_frequency = 1,
- text_scale = 1,
- }
- -- Loads custom options from file (if available)
- if fs.exists('config') then
- -- Opens the file for reading
- local handle = fs.open('config')
- -- Reads configs
- raw_options = {}
- local line = handle.readLine()
- while line do
- table.insert(raw_options, line)
- line = handle.readLine()
- end
- -- Sets custom options
- custom_options = string.format('{%s}', table.concat(raw_options, '\n,'))
- -- Closes the handle properly
- handle.close()
- end
- -- Gets custom settings via arguments
- args = {...}
- if args and #args > 0 then
- -- Parses custom settings from args
- custom_options = string.format('{%s}', table.concat(args, '\n,'))
- end
- -- Detects custom options
- if custom_options then
- -- Debug only
- print('Running with custom options:')
- -- Makes sure we're dealing with a table to prevent code injection
- if '{' == custom_options:sub(1, 1) then
- -- Parses the object
- custom_options, err = loadstring(string.format('return %s', custom_options))
- -- Handles invalid object
- if not custom_options then
- print('Invalid options:')
- print(err)
- else
- -- Replaces settings
- for k, v in pairs(custom_options()) do
- print(string.format('%s = %s', k, v))
- options[k] = v
- end
- end
- end
- end
- -- Auto-detects sides
- for _, side in pairs(peripheral.getNames()) do
- -- Auto-detects monitor
- if 'monitor' == peripheral.getType(side) and (not options.side_monitor) then
- options.side_monitor = side
- end
- -- Auto-detects Induction Port
- if 'inductionPort' == peripheral.getType(side) and (not options.side_inductor) then
- options.side_inductor = side
- end
- end
- -- Connects to Peripherals
- monitor = peripheral.wrap(options.side_monitor)
- -- Queues a new print command to be sent
- buffer = {}
- function queue (text)
- table.insert(buffer, text)
- end
- -- Queues a new print command with string.format
- function queuef (fmt, ...)
- queue(string.format(fmt, ...))
- end
- -- Flushes (prints) buffer content
- function queue_flush ()
- -- Clears terminal
- term.clear()
- term.setCursorPos(1, 1)
- -- Writes new data, center aligned
- local w, h = term.getSize()
- local y_offset = math.ceil(h / 2 - #buffer / 2) - 1
- for y, line in ipairs(buffer) do
- term.setCursorPos(
- math.ceil(w / 2 - #line / 2),
- y + y_offset
- )
- term.write(line)
- end
- buffer = {}
- end
- -- Formats time
- function time (secs)
- -- Prepare value
- secs = math.floor(secs)
- -- Days
- local weeks = math.floor(secs / 604800)
- secs = secs - (604800 * weeks)
- -- Days
- local days = math.floor(secs / 86400)
- secs = secs - (86400 * days)
- -- Hours
- local hours = math.floor(secs / 3600)
- secs = secs - (3600 * hours)
- -- Minutes
- local mins = math.floor(secs / 60)
- secs = secs - (60 * mins)
- -- If we have more than 72h worth of storage, switch to week, day, hour format
- if weeks > 0 then
- return string.format('%dwk %dd %dh', weeks, days, hours)
- elseif days >= 3 then
- return string.format('%dd %dh', days, hours)
- end
- -- Formatting to have trailing zeros on H:MM:SS
- return string.format('%d:%02d:%02d', hours, mins, secs)
- end
- -- Rounds number
- function rnd (val, dec)
- local X = math.pow(10, dec)
- return math.floor(val * X) / X
- end
- -- Converts to percentage
- function pct (val, dec)
- return rnd(100 * val, dec or 1) .. '%'
- end
- -- Converts to readable power
- function pwr (val, dec)
- local pre = ''
- local suf = ''
- local is_neg = false
- if val < 0 then
- pre = '-'
- is_neg = true
- val = -val
- end
- val = energy_function(val)
- if val > 1000 then
- suf = 'k'
- val = val / 1000
- end
- if val > 1000 then
- suf = 'M'
- val = val / 1000
- end
- if val > 1000 then
- suf = 'G'
- val = val / 1000
- end
- if val > 1000 then
- suf = 'T'
- val = val / 1000
- end
- return string.format('%s%s%s%s', pre, rnd(val, dec or 1), suf, energy_type)
- end
- -- Checks induction port
- function check_connection ()
- return inductor and inductor.getEnergy and inductor.getLastInput
- end
- -- Detects energy type, sets energy function
- energy_type = options.energy_type
- energy_function = mekanismEnergyHelper[string.format('joulesTo%s', energy_type)]
- -- Function not found, use default Joules and a stub
- if not energy_function then
- energy_type = 'J'
- energy_function = function (val) return val end
- end
- -- Starts monitor
- term.redirect(monitor)
- monitor.setTextScale(options.text_scale)
- -- Checks if Inductor Port is missing or multiblock not ready
- inductor = peripheral.wrap(options.side_inductor)
- while not check_connection() do
- -- Writes error message
- queue('Ind.Port not found')
- queue('Check connections.')
- queue('Waiting...')
- -- Prints
- queue_flush()
- -- Wait for next update
- os.sleep(options.update_frequency)
- -- Tries to detect port
- if not options.side_inductor then
- for _, side in pairs(peripheral.getNames()) do
- -- Tries to find an induction port
- if 'inductionPort' == peripheral.getType(side) then
- options.side_inductor = side
- inductor = peripheral.wrap(options.side_inductor)
- end
- end
- else
- -- Try again on pre-set port
- inductor = peripheral.wrap(options.side_inductor)
- end
- end
- -- Initializes balance
- balance = inductor.getEnergy()
- while true do
- local status, err = pcall(function ()
- -- Main script
- queue('Ind.Matrix Monitor')
- queue('------------------')
- queue('')
- queuef('Power : %s', pwr(inductor.getEnergy()))
- queuef('Limit : %s', pwr(inductor.getMaxEnergy()))
- queuef('Charge: %s', pct(inductor.getEnergyFilledPercentage()))
- queue('')
- queuef('Input : %s', pwr(inductor.getLastInput()))
- queuef('Output: %s', pwr(inductor.getLastOutput()))
- queuef('Max IO: %s/t', pwr(inductor.getTransferCap()))
- queue('')
- -- Power balance per second
- local balance_last = balance
- balance = inductor.getEnergy()
- local balance_change = (balance - balance_last) / options.update_frequency
- -- If we have negative value here, we'll save a character by removing the space so it fits same line
- if balance_change < 0 then
- queuef('Change:%s/s', pwr(balance_change))
- else
- queuef('Change: %s/s', pwr(balance_change))
- end
- -- Status (charged/depleted in)
- queue('Status:')
- if balance_change > 0 then
- -- Charging
- local remaining_charge = inductor.getMaxEnergy() - inductor.getEnergy()
- local seconds_remaining = remaining_charge / balance_change
- queuef('Charg. %s', time(seconds_remaining))
- elseif balance_change < 0 then
- -- Discharging
- local remaining_charge = inductor.getEnergy()
- local seconds_remaining = remaining_charge / -balance_change
- queuef('Disch. %s', time(seconds_remaining))
- else
- -- No changes, so we won't be charged or depleted, rare.
- queue('Idle')
- end
- end)
- -- Checks for errors (might be disconnected)
- if not status then
- -- Clears buffer first
- buffer = {}
- -- Shows error message
- queue('Error reading data')
- queue('Check connections.')
- queue('------------------')
- queue(err)
- end
- -- Prints
- queue_flush()
- -- Wait for next update
- os.sleep(options.update_frequency)
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement