Skip to content

Commit

Permalink
Merge pull request #52 from cyberbit/feature/fluent-mekanism
Browse files Browse the repository at this point in the history
Refactor internals for Mekanism inputs
  • Loading branch information
cyberbit authored Jun 16, 2024
2 parents 07524b7 + 7fa8329 commit cd99739
Show file tree
Hide file tree
Showing 9 changed files with 314 additions and 319 deletions.
6 changes: 3 additions & 3 deletions docs/reference/input/mekanism/IndustrialTurbine.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,21 +137,21 @@ DUMPING_MODES = { IDLE = 1, DUMPING_EXCESS = 2, DUMPING = 3 }
:metrics="[
{
name: 'mekturbine:energy',
value: '0 - inf',
value: '0.0 - inf',
unit: 'FE',
adapter: 'my_turbine',
source: 'right'
},
{
name: 'mekturbine:max_energy',
value: '0 - inf',
value: '0.0 - inf',
unit: 'FE',
adapter: 'my_turbine',
source: 'right'
},
{
name: 'mekturbine:energy_needed',
value: '0 - inf',
value: '0.0 - inf',
unit: 'FE',
adapter: 'my_turbine',
source: 'right'
Expand Down
4 changes: 2 additions & 2 deletions src/telem/init.lua
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
-- Telem by cyberbit
-- MIT License
-- Version 0.7.0
-- Version 0.7.1

local _Telem = {
_VERSION = '0.7.0',
_VERSION = '0.7.1',
util = require 'telem.lib.util',
input = require 'telem.lib.input',
output = require 'telem.lib.output',
Expand Down
55 changes: 55 additions & 0 deletions src/telem/lib/input/mekanism/BaseMekanismInputAdapter.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
local o = require 'telem.lib.ObjectModel'
local t = require 'telem.lib.util'

local InputAdapter = require 'telem.lib.InputAdapter'
local Metric = require 'telem.lib.Metric'
local MetricCollection = require 'telem.lib.MetricCollection'

local BaseMekanismInputAdapter = o.class(InputAdapter)
BaseMekanismInputAdapter.type = 'BaseMekanismInputAdapter'

function BaseMekanismInputAdapter:constructor (peripheralName)
self:super('constructor')

self.prefix = 'mek:'

self.queries = {}

-- boot components
self:setBoot(function ()
self.components = {}

self:addComponentByPeripheralID(peripheralName)
end)()
end

local function queueHelper (results, index, query)
return function ()
results[index] = Metric(query:metricable():result())
end
end

function BaseMekanismInputAdapter:read ()
self:boot()

local source, component = next(self.components)

local tempMetrics = {}
local queue = {}

for _, category in ipairs(self.categories) do
for k, v in pairs(self.queries[category]) do
table.insert(queue, queueHelper(
tempMetrics,
#queue + 1,
v:from(component):with('name', self.prefix .. k):with('source', source)
))
end
end

parallel.waitForAll(table.unpack(queue))

return MetricCollection(table.unpack(tempMetrics))
end

return BaseMekanismInputAdapter
138 changes: 54 additions & 84 deletions src/telem/lib/input/mekanism/FissionReactorInputAdapter.lua
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
local o = require 'telem.lib.ObjectModel'
local t = require 'telem.lib.util'
local fn = require 'telem.vendor'.fluent.fn

local InputAdapter = require 'telem.lib.InputAdapter'
local Metric = require 'telem.lib.Metric'
local MetricCollection = require 'telem.lib.MetricCollection'
local BaseMekanismInputAdapter = require 'telem.lib.input.mekanism.BaseMekanismInputAdapter'

local FissionReactorInputAdapter = o.class(InputAdapter)
local FissionReactorInputAdapter = o.class(BaseMekanismInputAdapter)
FissionReactorInputAdapter.type = 'FissionReactorInputAdapter'

function FissionReactorInputAdapter:constructor (peripheralName, categories)
self:super('constructor')
self:super('constructor', peripheralName)

-- TODO this will be a configurable feature later
self.prefix = 'mekfission:'
Expand All @@ -32,86 +31,57 @@ function FissionReactorInputAdapter:constructor (peripheralName, categories)
self.categories = categories
end

-- boot components
self:setBoot(function ()
self.components = {}

self:addComponentByPeripheralID(peripheralName)
end)()
end

function FissionReactorInputAdapter:read ()
self:boot()

local source, fission = next(self.components)

local metrics = MetricCollection()

local loaded = {}

for _,v in ipairs(self.categories) do
-- skip, already loaded
if loaded[v] then
-- do nothing

-- minimum necessary for monitoring a fission reactor safely
elseif v == 'basic' then
metrics:insert(Metric{ name = self.prefix .. 'status', value = (fission.getStatus() and 1 or 0), unit = nil, source = source })
metrics:insert(Metric{ name = self.prefix .. 'burn_rate', value = fission.getBurnRate() / 1000, unit = 'B/t', source = source })
metrics:insert(Metric{ name = self.prefix .. 'max_burn_rate', value = fission.getMaxBurnRate() / 1000, unit = 'B/t', source = source })
metrics:insert(Metric{ name = self.prefix .. 'temperature', value = fission.getTemperature(), unit = 'K', source = source })
metrics:insert(Metric{ name = self.prefix .. 'damage_percent', value = fission.getDamagePercent(), unit = nil, source = source })
metrics:insert(Metric{ name = self.prefix .. 'fuel_filled_percentage', value = fission.getFuelFilledPercentage(), unit = nil, source = source })
metrics:insert(Metric{ name = self.prefix .. 'coolant_filled_percentage', value = fission.getCoolantFilledPercentage(), unit = nil, source = source })
metrics:insert(Metric{ name = self.prefix .. 'heated_coolant_filled_percentage', value = fission.getHeatedCoolantFilledPercentage(), unit = nil, source = source })
metrics:insert(Metric{ name = self.prefix .. 'waste_filled_percentage', value = fission.getWasteFilledPercentage(), unit = nil, source = source })

-- some further production metrics
elseif v == 'advanced' then
metrics:insert(Metric{ name = self.prefix .. 'actual_burn_rate', value = fission.getActualBurnRate() / 1000, unit = 'B/t', source = source })
metrics:insert(Metric{ name = self.prefix .. 'environmental_loss', value = fission.getEnvironmentalLoss(), unit = nil, source = source })
metrics:insert(Metric{ name = self.prefix .. 'heating_rate', value = fission.getHeatingRate() / 1000, unit = 'B/t', source = source })

elseif v == 'coolant' then
metrics:insert(Metric{ name = self.prefix .. 'coolant', value = fission.getCoolant().amount / 1000, unit = 'B', source = source })
metrics:insert(Metric{ name = self.prefix .. 'coolant_capacity', value = fission.getCoolantCapacity() / 1000, unit = 'B', source = source })
metrics:insert(Metric{ name = self.prefix .. 'coolant_needed', value = fission.getCoolantNeeded() / 1000, unit = 'B', source = source })
metrics:insert(Metric{ name = self.prefix .. 'heated_coolant', value = fission.getHeatedCoolant().amount / 1000, unit = 'B', source = source })
metrics:insert(Metric{ name = self.prefix .. 'heated_coolant_capacity', value = fission.getHeatedCoolantCapacity() / 1000, unit = 'B', source = source })
metrics:insert(Metric{ name = self.prefix .. 'heated_coolant_needed', value = fission.getHeatedCoolantNeeded() / 1000, unit = 'B', source = source })

elseif v == 'fuel' then
metrics:insert(Metric{ name = self.prefix .. 'fuel', value = fission.getFuel().amount / 1000, unit = 'B', source = source })
metrics:insert(Metric{ name = self.prefix .. 'fuel_capacity', value = fission.getFuelCapacity() / 1000, unit = 'B', source = source })
metrics:insert(Metric{ name = self.prefix .. 'fuel_needed', value = fission.getFuelNeeded(), unit = 'B', source = source })

elseif v == 'waste' then
metrics:insert(Metric{ name = self.prefix .. 'waste', value = fission.getWaste().amount / 1000, unit = 'B', source = source })
metrics:insert(Metric{ name = self.prefix .. 'waste_capacity', value = fission.getWasteCapacity() / 1000, unit = 'B', source = source })
metrics:insert(Metric{ name = self.prefix .. 'waste_needed', value = fission.getWasteNeeded() / 1000, unit = 'B', source = source })

-- measurements based on the multiblock structure itself
elseif v == 'formation' then
metrics:insert(Metric{ name = self.prefix .. 'formed', value = (fission.isFormed() and 1 or 0), unit = nil, source = source })
metrics:insert(Metric{ name = self.prefix .. 'force_disabled', value = (fission.isForceDisabled() and 1 or 0), unit = nil, source = source })
metrics:insert(Metric{ name = self.prefix .. 'height', value = fission.getHeight(), unit = 'm', source = source })
metrics:insert(Metric{ name = self.prefix .. 'length', value = fission.getLength(), unit = 'm', source = source })
metrics:insert(Metric{ name = self.prefix .. 'width', value = fission.getWidth(), unit = 'm', source = source })
metrics:insert(Metric{ name = self.prefix .. 'fuel_assemblies', value = fission.getFuelAssemblies(), unit = nil, source = source })
metrics:insert(Metric{ name = self.prefix .. 'fuel_surface_area', value = fission.getFuelSurfaceArea(), unit = '', source = source })
metrics:insert(Metric{ name = self.prefix .. 'heat_capacity', value = fission.getHeatCapacity(), unit = 'J/K', source = source })
metrics:insert(Metric{ name = self.prefix .. 'boil_efficiency', value = fission.getBoilEfficiency(), unit = nil, source = source })
end

loaded[v] = true

-- not sure if these are useful, but they return strings anyway which are not Metric compatible, RIP
-- metrics:insert(Metric{ name = self.prefix .. 'logic_mode', value = fission.getLogicMode(), unit = nil, source = source })
-- metrics:insert(Metric{ name = self.prefix .. 'redstone_logic_status', value = fission.getRedstoneLogicStatus(), unit = nil, source = source })
-- metrics:insert(Metric{ name = self.prefix .. 'redstone_mode', value = fission.getRedstoneLogicStatus(), unit = nil, source = source })
end
self.queries = {
basic = {
status = fn():call('getStatus'):toFlag(),
burn_rate = fn():call('getBurnRate'):div(1000):fluidRate(),
max_burn_rate = fn():call('getMaxBurnRate'):div(1000):fluidRate(),
temperature = fn():call('getTemperature'):temp(),
damage_percent = fn():call('getDamagePercent'),
fuel_filled_percentage = fn():call('getFuelFilledPercentage'),
coolant_filled_percentage = fn():call('getCoolantFilledPercentage'),
heated_coolant_filled_percentage = fn():call('getHeatedCoolantFilledPercentage'),
waste_filled_percentage = fn():call('getWasteFilledPercentage')
},
advanced = {
actual_burn_rate = fn():call('getActualBurnRate'):div(1000):fluidRate(),
environmental_loss = fn():call('getEnvironmentalLoss'),
heating_rate = fn():call('getHeatingRate'):div(1000):fluidRate(),
},
coolant = {
coolant = fn():call('getCoolant'):get('amount'):div(1000):fluid(),
coolant_capacity = fn():call('getCoolantCapacity'):div(1000):fluid(),
coolant_needed = fn():call('getCoolantNeeded'):div(1000):fluid(),
heated_coolant = fn():call('getHeatedCoolant'):get('amount'):div(1000):fluid(),
heated_coolant_capacity = fn():call('getHeatedCoolantCapacity'):div(1000):fluid(),
heated_coolant_needed = fn():call('getHeatedCoolantNeeded'):div(1000):fluid()
},
fuel = {
fuel = fn():call('getFuel'):get('amount'):div(1000):fluid(),
fuel_capacity = fn():call('getFuelCapacity'):div(1000):fluid(),
fuel_needed = fn():call('getFuelNeeded'):div(1000):fluid()
},
waste = {
waste = fn():call('getWaste'):get('amount'):div(1000):fluid(),
waste_capacity = fn():call('getWasteCapacity'):div(1000):fluid(),
waste_needed = fn():call('getWasteNeeded'):div(1000):fluid()
},
formation = {
formed = fn():call('isFormed'):toFlag(),
force_disabled = fn():call('isForceDisabled'):toFlag(),
height = fn():call('getHeight'):with('unit', 'm'),
length = fn():call('getLength'):with('unit', 'm'),
width = fn():call('getWidth'):with('unit', 'm'),
fuel_assemblies = fn():call('getFuelAssemblies'),
fuel_surface_area = fn():call('getFuelSurfaceArea'):with('unit', ''),
heat_capacity = fn():call('getHeatCapacity'):with('unit', 'J/K'),
boil_efficiency = fn():call('getBoilEfficiency')
}
}

return metrics
-- not sure if these are useful, but they return strings anyway which are not Metric compatible, RIP
-- fission.getLogicMode()
-- fission.getRedstoneLogicStatus()
end

return FissionReactorInputAdapter
Loading

0 comments on commit cd99739

Please sign in to comment.