Advertisement
wolfe_br

Mekanism Induction Matrix Manager v2 (Receiver Module)

Jun 24th, 2023 (edited)
3,665
1
Never
1
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 9.10 KB | Gaming | 1 0
  1. --[[
  2.   Wolfe's Mekanism Induction Matrix Monitor v2 (Receiver Module)
  3.   Usage: Put computer near Modem and Monitor (2x3 array should work fine) and install. Requires another computer transmitting matrix data over rednet to work.
  4.   Installation: pastebin run 3naSaR8X install
  5.   Configuration: Edit the "config" file, refer to the comments below for what each field means
  6. ]]
  7.  
  8. -- Default settings, do not change
  9. local options = {
  10.   -- Unique identifier for the destination matrix on rednet
  11.   rednet_identifier = '',
  12.  
  13.   -- Energy type being displayed (J, FE)
  14.   energy_type = 'FE',
  15.  
  16.   -- Text scale on the monitor
  17.   text_scale = 1,
  18.  
  19.   -- Output debug data to the computer's internal display
  20.   debug = true,
  21. }
  22.  
  23. --------------------------------------------------
  24. --- Internal variables, DO NOT CHANGE
  25. --------------------------------------------------
  26.  
  27. --- This will be used as the installer source (Pastebin)
  28. local INSTALLER_ID = '3naSaR8X'
  29.  
  30. --- Supported energy suffixes
  31. local energy_suffixes = { 'k', 'M', 'G', 'T', 'P' }
  32.  
  33. --- Supported time periods when converting seconds
  34. local time_periods = {
  35.   { 'weeks', 604800 },
  36.   { 'days', 86400 },
  37.   { 'hours', 3600 },
  38.   { 'minutes', 60 },
  39.   { 'seconds', 1 },
  40. }
  41.  
  42. --- This is our Induction Matrix, we'll auto-detect it later
  43. local induction_matrix = nil
  44.  
  45. --- This is our Monitor, we'll auto-detect it later
  46. local monitor = nil
  47.  
  48. --- This is our Modem, we'll auto-detect it later
  49. local modem = nil
  50.  
  51. --- Prefix used for rednet channels
  52. local rednet_prefix = 'WL_Mek_Matrix'
  53.  
  54. --------------------------------------------------
  55. --- Helper functions
  56. --------------------------------------------------
  57.  
  58. --- Reads a file's contents
  59. ---@return string
  60. function file_read (file)
  61.   local handle = fs.open(file, 'r')
  62.   local data = handle.readAll()
  63.   handle.close()
  64.   return data
  65. end
  66.  
  67. --- Writes data to a file (overrides existing data)
  68. function file_write (file, data)
  69.   local handle = fs.open(file, 'w')
  70.   handle.write(data)
  71.   handle.close()
  72. end
  73.  
  74. --- Holds the current buffer of data being printed
  75. local machine_term = term.current()
  76. local print_buffer = {}
  77.  
  78. --- Writes data to the output monitor buffer
  79. function print_r (text)
  80.   table.insert(print_buffer, text)
  81. end
  82.  
  83. --- Writes formatted data to the output monitor buffer
  84. function print_f (format, ...)
  85.   print_r(string.format(format, ...))
  86. end
  87.  
  88. --- Writes the buffer into the output monitor
  89. function print_flush ()
  90.   -- Redirects writes to monitor (if any)
  91.   term.redirect(monitor)
  92.  
  93.   -- Clears terminal
  94.   term.clear()
  95.   term.setCursorPos(1, 1)
  96.  
  97.   -- Writes new data
  98.   print(table.concat(print_buffer or {}, '\n'))
  99.  
  100.   -- Redirects writes back to computer (if using monitor)
  101.   term.redirect(machine_term)
  102.  
  103.   -- Clears buffer
  104.   print_buffer = {}
  105. end
  106.  
  107. --- Writes debug info to the machine
  108. function debug (...)
  109.   if options.debug then
  110.     print(...)
  111.   end
  112. end
  113.  
  114. --- Rounds a number with N decimals
  115. function round_decimal (number, decimals)
  116.   local multiplier = math.pow(10, decimals or 0)
  117.   return math.floor(number * multiplier) / multiplier
  118. end
  119.  
  120. --- Rounds a percentage (0..1) to a number of decimals
  121. function round_percentage (number, decimals)
  122.   return ('%s%%'):format(round_decimal(100 * number, decimals or 1))
  123. end
  124.  
  125. --- The current energy type
  126. local energy_type = 'J'
  127.  
  128. --- Converts energy values
  129. local energy_convert = function (energy) return energy end
  130. if mekanismEnergyHelper and mekanismEnergyHelper[('joulesTo%s'):format(options.energy_type)] then
  131.   energy_type = options.energy_type
  132.   energy_convert = mekanismEnergyHelper[('joulesTo%s'):format(options.energy_type)]
  133. end
  134.  
  135. --- Prints an energy value
  136. local energy_string = function (energy, decimals)
  137.   local prefix = ''
  138.   local suffix = ''
  139.  
  140.   -- Prepares a prefix for negative numbers
  141.   if energy < 0 then
  142.     prefix = '-'
  143.   end
  144.  
  145.   -- We need a positive number here for calculating multipliers (k, M, G, T), we'll add the minus later, we also convert it to the right unit
  146.   local amount = energy_convert(math.abs(energy))
  147.  
  148.   -- Finds the proper suffix/multiplier
  149.   for _, multiplier in pairs(energy_suffixes) do
  150.     -- Stops when amount is less than 1000
  151.     if amount < 1000 then
  152.       break
  153.     end
  154.  
  155.     -- Updates suffix and amount to new value
  156.     amount = amount / 1000
  157.     suffix = multiplier
  158.   end
  159.  
  160.   -- Returns the formatted string
  161.   return ('%s%s%s%s'):format(prefix, round_decimal(amount, decimals or 1), suffix, energy_type)
  162. end
  163.  
  164. --- Generates an ETA string when given a number of seconds
  165. function eta_string (seconds)
  166.   -- Makes sure we're only dealing with integers
  167.   seconds = math.floor(seconds)
  168.  
  169.   -- Processes time periods
  170.   local time = {}
  171.   for _, period in pairs(time_periods) do
  172.     local count = math.floor(seconds / period[2])
  173.     time[period[1]] = count
  174.     seconds = seconds - (count * period[2])
  175.   end
  176.  
  177.   -- If we have more than 72h worth of storage, switch to week, day, hour format
  178.   if time.weeks > 0 then
  179.     return ('%dwk %dd %dh'):format(time.weeks, time.days, time.hours)
  180.   elseif time.days >= 3 then
  181.     return ('%dd %dh'):format(time.days, time.hours)
  182.   end
  183.  
  184.   -- For all other cases, we'll just use H:MM:SS
  185.   return ('%d:%02d:%02d'):format(time.hours, time.minutes, time.seconds)
  186. end
  187.  
  188. --- Prints the Induction Matrix information
  189. function print_matrix_info (matrix_info)
  190.   print_r('Ind.Matrix Monitor')
  191.   print_r('------------------')
  192.   print_r('')
  193.   print_f('Power : %s', energy_string(matrix_info.energy_stored))
  194.   print_f('Limit : %s', energy_string(matrix_info.energy_capacity))
  195.   print_f('Charge: %s', round_percentage(matrix_info.energy_percentage))
  196.   print_r('')
  197.   print_f('Input : %s/t', energy_string(matrix_info.io_input))
  198.   print_f('Output: %s/t', energy_string(matrix_info.io_output))
  199.   print_f('Max IO: %s/t', energy_string(matrix_info.io_capacity))
  200.   print_r('')
  201.  
  202.   -- If we have negative value here, we'll save a character by removing the space so it fits same line
  203.   if matrix_info.change_amount < 0 then
  204.     print_f('Change:%s/s', energy_string(matrix_info.change_amount_per_second))
  205.   else
  206.     print_f('Change: %s/s', energy_string(matrix_info.change_amount_per_second))
  207.   end
  208.  
  209.   -- Charge/discharge status
  210.   print_r('Status:')
  211.   if matrix_info.is_charging then
  212.     print_f('Charg. %s', eta_string((matrix_info.energy_capacity - matrix_info.energy_stored) / matrix_info.change_amount_per_second))
  213.   elseif matrix_info.is_discharging then
  214.     print_f('Disch. %s', eta_string(matrix_info.energy_stored / math.abs(matrix_info.change_amount_per_second)))
  215.   else
  216.     print_r('Idle')
  217.   end
  218. end
  219.  
  220. --------------------------------------------------
  221. --- Program initialization
  222. --------------------------------------------------
  223.  
  224. args = {...}
  225.  
  226. -- Loads custom options from filesystem
  227. if fs.exists('config') then
  228.   debug('Loading settings from "config" file...')
  229.  
  230.   -- Reads custom options
  231.   local custom_options = textutils.unserialize(file_read('config'))
  232.  
  233.   -- Overrides each of the existing options
  234.   for k, v in pairs(custom_options) do
  235.     options[k] = v
  236.   end
  237. end
  238.  
  239. -- Writes back config file
  240. print('Updating config file...')
  241. file_write('config', textutils.serialize(options))
  242.  
  243. -- Handles special case when "install" is executed from the pastebin
  244. if 'install' == args[1] then
  245.   print('Installing Matrix Monitor (Receiver Module)...')
  246.  
  247.   -- Are we on first install? If so, we'll run open the config for editing later
  248.   local has_existing_install = fs.exists('startup.lua')
  249.  
  250.   -- Removes existing version
  251.   if fs.exists('startup.lua') then
  252.     fs.delete('startup.lua')
  253.   end
  254.  
  255.   -- Downloads script from Pastebin
  256.   shell.run('pastebin', 'get', INSTALLER_ID, 'startup.lua')
  257.  
  258.   -- Runs config editor
  259.   if not has_existing_install then
  260.     print('Opening config file for editing...')
  261.     sleep(2.5)
  262.     shell.run('edit', 'config')
  263.   end
  264.  
  265.   -- Reboots the computer after everything is done
  266.   print('Install complete! Restarting computer...')
  267.   sleep(2.5)
  268.   os.reboot()
  269. end
  270.  
  271. -- Detects peripherals
  272. monitor = peripheral.find('monitor')
  273. modem = peripheral.find('modem')
  274.  
  275. --- The rednet channel/protocol we'll be using
  276. local rednet_channel = nil
  277.  
  278. -- Makes sure we have a connected monitor
  279. if monitor then
  280.   monitor.setTextScale(options.text_scale)
  281. else
  282.   error('No monitor detected!')
  283. end
  284.  
  285. -- Makes sure we have a connected modem
  286. if modem then
  287.   if not options.rednet_identifier or options.rednet_identifier == '' then
  288.     error('Modem has been found, but no wireless identifier found on configs!')
  289.   end
  290.  
  291.   peripheral.find('modem', rednet.open)
  292.   debug('Connected to rednet!')
  293.   rednet_channel = ('%s#%s'):format(rednet_prefix, options.rednet_identifier)
  294. else
  295.   error('No modem detected!')
  296. end
  297.  
  298. --------------------------------------------------
  299. --- Main runtime
  300. --------------------------------------------------
  301.  
  302. debug('Entering main loop...')
  303.  
  304. while true do
  305.   -- Receives next update
  306.   local id, message = rednet.receive(rednet_channel)
  307.  
  308.   -- Parses message
  309.   local matrix_info = textutils.unserialize(message)
  310.  
  311.   -- Prints the matrix information
  312.   print_matrix_info(matrix_info)
  313.  
  314.   -- Outputs text to screen
  315.   print_flush()
  316. end
Advertisement
Comments
  • Cakanr
    344 days
    # text 0.21 KB | 0 0
    1. I'm new to CC: Tweaked (computercraft on craft os 1.8) I gave up to set up ender modem (I connect them with rednet but still don't work) but wire one work, I don't understand how to change color, can you help me ?
Add Comment
Please, Sign In to add comment
Advertisement