diff --git a/docs/reference/input/mekanism/IndustrialTurbine.md b/docs/reference/input/mekanism/IndustrialTurbine.md index f81402e..4c952cc 100644 --- a/docs/reference/input/mekanism/IndustrialTurbine.md +++ b/docs/reference/input/mekanism/IndustrialTurbine.md @@ -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' diff --git a/src/telem/init.lua b/src/telem/init.lua index 20b65ea..ecbbf34 100644 --- a/src/telem/init.lua +++ b/src/telem/init.lua @@ -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', diff --git a/src/telem/lib/input/mekanism/BaseMekanismInputAdapter.lua b/src/telem/lib/input/mekanism/BaseMekanismInputAdapter.lua new file mode 100644 index 0000000..0057ef3 --- /dev/null +++ b/src/telem/lib/input/mekanism/BaseMekanismInputAdapter.lua @@ -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 \ No newline at end of file diff --git a/src/telem/lib/input/mekanism/FissionReactorInputAdapter.lua b/src/telem/lib/input/mekanism/FissionReactorInputAdapter.lua index 530697c..77ff942 100644 --- a/src/telem/lib/input/mekanism/FissionReactorInputAdapter.lua +++ b/src/telem/lib/input/mekanism/FissionReactorInputAdapter.lua @@ -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:' @@ -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 = 'm²', 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', 'm²'), + 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 \ No newline at end of file diff --git a/src/telem/lib/input/mekanism/FusionReactorInputAdapter.lua b/src/telem/lib/input/mekanism/FusionReactorInputAdapter.lua index 5b9cad9..46d998f 100644 --- a/src/telem/lib/input/mekanism/FusionReactorInputAdapter.lua +++ b/src/telem/lib/input/mekanism/FusionReactorInputAdapter.lua @@ -1,15 +1,21 @@ 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 FusionReactorInputAdapter = o.class(InputAdapter) +local FusionReactorInputAdapter = o.class(BaseMekanismInputAdapter) FusionReactorInputAdapter.type = 'FusionReactorInputAdapter' +-- alternative call that passes another call as a parameter +local callIsActiveCooled = function (method) + return function (v) + return v[method](v.isActiveCooledLogic()) + end +end + function FusionReactorInputAdapter:constructor (peripheralName, categories) - self:super('constructor') + self:super('constructor', peripheralName) -- TODO this will be a configurable feature later self.prefix = 'mekfusion:' @@ -31,87 +37,49 @@ function FusionReactorInputAdapter:constructor (peripheralName, categories) self.categories = categories end - -- boot components - self:setBoot(function () - self.components = {} - - self:addComponentByPeripheralID(peripheralName) - end)() -end - -function FusionReactorInputAdapter:read () - self:boot() - - local source, fusion = 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 fusion reactor - elseif v == 'basic' then - local isActive = fusion.isActiveCooledLogic() - metrics:insert(Metric{ name = self.prefix .. 'plasma_temperature', value = fusion.getPlasmaTemperature(), unit = 'K', source = source }) - metrics:insert(Metric{ name = self.prefix .. 'case_temperature', value = fusion.getCaseTemperature(), unit = 'K', source = source }) - metrics:insert(Metric{ name = self.prefix .. 'water_filled_percentage', value = fusion.getWaterFilledPercentage(), unit = nil, source = source }) - metrics:insert(Metric{ name = self.prefix .. 'steam_filled_percentage', value = fusion.getSteamFilledPercentage(), unit = nil, source = source }) - metrics:insert(Metric{ name = self.prefix .. 'tritium_filled_percentage', value = fusion.getTritiumFilledPercentage(), unit = nil, source = source }) - metrics:insert(Metric{ name = self.prefix .. 'deuterium_filled_percentage', value = fusion.getDeuteriumFilledPercentage(), unit = nil, source = source }) - metrics:insert(Metric{ name = self.prefix .. 'dt_fuel_filled_percentage', value = fusion.getDTFuelFilledPercentage(), unit = nil, source = source }) - metrics:insert(Metric{ name = self.prefix .. 'production_rate', value = mekanismEnergyHelper.joulesToFE(fusion.getProductionRate()), unit = nil, source = source }) - metrics:insert(Metric{ name = self.prefix .. 'injection_rate', value = fusion.getInjectionRate() / 1000, unit = 'B/t', source = source }) - metrics:insert(Metric{ name = self.prefix .. 'min_injection_rate', value = fusion.getMinInjectionRate(isActive) / 1000, unit = 'B/t', source = source }) - metrics:insert(Metric{ name = self.prefix .. 'max_plasma_temperature', value = fusion.getMaxPlasmaTemperature(isActive), unit = 'K', source = source }) - metrics:insert(Metric{ name = self.prefix .. 'max_casing_temperature', value = fusion.getMaxCasingTemperature(isActive), unit = 'K', source = source }) - metrics:insert(Metric{ name = self.prefix .. 'passive_generation_rate', value = mekanismEnergyHelper.joulesToFE(fusion.getPassiveGeneration(isActive)), unit = 'FE/t', source = source }) - metrics:insert(Metric{ name = self.prefix .. 'ignition_temperature', value = fusion.getIgnitionTemperature(isActive), unit = 'K', source = source }) - - -- some further production metrics - elseif v == 'advanced' then - -- metrics:insert(Metric{ name = self.prefix .. 'transfer_loss', value = fusion.getTransferLoss(), unit = nil, source = source }) - -- metrics:insert(Metric{ name = self.prefix .. 'environmental_loss', value = fusion.getEnvironmentalLoss(), unit = nil, source = source }) - - elseif v == 'coolant' then - metrics:insert(Metric{ name = self.prefix .. 'water_capacity', value = fusion.getWaterCapacity() / 1000, unit = 'B', source = source }) - metrics:insert(Metric{ name = self.prefix .. 'water_needed', value = fusion.getWaterNeeded() / 1000, unit = 'B', source = source }) - metrics:insert(Metric{ name = self.prefix .. 'steam_capacity', value = fusion.getSteamCapacity() / 1000, unit = 'B', source = source }) - metrics:insert(Metric{ name = self.prefix .. 'steam_needed', value = fusion.getSteamNeeded() / 1000, unit = 'B', source = source }) - - elseif v == 'fuel' then - metrics:insert(Metric{ name = self.prefix .. 'tritium_capacity', value = fusion.getTritiumCapacity() / 1000, unit = 'B', source = source }) - metrics:insert(Metric{ name = self.prefix .. 'tritium_needed', value = fusion.getTritiumNeeded() / 1000, unit = 'B', source = source }) - metrics:insert(Metric{ name = self.prefix .. 'deuterium_capacity', value = fusion.getDeuteriumCapacity() / 1000, unit = 'B', source = source }) - metrics:insert(Metric{ name = self.prefix .. 'deuterium_needed', value = fusion.getDeuteriumNeeded() / 1000, unit = 'B', source = source }) - metrics:insert(Metric{ name = self.prefix .. 'dt_fuel_capacity', value = fusion.getDTFuelCapacity() / 1000, unit = 'B', source = source }) - metrics:insert(Metric{ name = self.prefix .. 'dt_fuel_needed', value = fusion.getDTFuelNeeded() / 1000, unit = 'B', source = source }) - - -- measurements based on the multiblock structure itself - elseif v == 'formation' then - metrics:insert(Metric{ name = self.prefix .. 'formed', value = (fusion.isFormed() and 1 or 0), unit = nil, source = source }) - metrics:insert(Metric{ name = self.prefix .. 'height', value = fusion.getHeight(), unit = 'm', source = source }) - metrics:insert(Metric{ name = self.prefix .. 'length', value = fusion.getLength(), unit = 'm', source = source }) - metrics:insert(Metric{ name = self.prefix .. 'width', value = fusion.getWidth(), unit = 'm', source = source }) - metrics:insert(Metric{ name = self.prefix .. 'active_cooled_logic', value = (fusion.isActiveCooledLogic() and 1 or 0), 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 = fusion.getLogicMode(), unit = nil, source = source }) - -- metrics:insert(Metric{ name = self.prefix .. 'tritium', value = fusion.getTritium() / 1000, unit = 'B', source = source }) - -- metrics:insert(Metric{ name = self.prefix .. 'deuterium', value = fusion.getDeuterium() / 1000, unit = 'B', source = source }) - -- metrics:insert(Metric{ name = self.prefix .. 'dt_fuel', value = fusion.getDTFuel() / 1000, unit = 'B', source = source }) - -- metrics:insert(Metric{ name = self.prefix .. 'hohlraum', value = fusion.getHohlraum(), unit = nil, source = source }) - -- metrics:insert(Metric{ name = self.prefix .. 'water', value = fusion.getWater() / 1000, unit = 'B', source = source }) - -- metrics:insert(Metric{ name = self.prefix .. 'steam', value = fusion.getSteam() / 1000, unit = 'B', source = source }) - end - - return metrics + self.queries = { + basic = { + plasma_temperature = fn():call('getPlasmaTemperature'):temp(), + case_temperature = fn():call('getCaseTemperature'):temp(), + water_filled_percentage = fn():call('getWaterFilledPercentage'), + steam_filled_percentage = fn():call('getSteamFilledPercentage'), + tritium_filled_percentage = fn():call('getTritiumFilledPercentage'), + deuterium_filled_percentage = fn():call('getDeuteriumFilledPercentage'), + dt_fuel_filled_percentage = fn():call('getDTFuelFilledPercentage'), + production_rate = fn():call('getProductionRate'):joulesToFE():energyRate(), + injection_rate = fn():call('getInjectionRate'):div(1000):fluidRate(), + min_injection_rate = fn():transform(callIsActiveCooled('getMinInjectionRate')):div(1000):fluidRate(), + max_plasma_temperature = fn():transform(callIsActiveCooled('getMaxPlasmaTemperature')):temp(), + max_casing_temperature = fn():transform(callIsActiveCooled('getMaxCasingTemperature')):temp(), + passive_generation_rate = fn():transform(callIsActiveCooled('getPassiveGeneration')):joulesToFE():energyRate(), + ignition_temperature = fn():transform(callIsActiveCooled('getIgnitionTemperature')):temp(), + }, + advanced = { + -- transfer_loss = fn():call('getTransferLoss'), + -- environmental_loss = fn():call('getEnvironmentalLoss'), + }, + coolant = { + water_capacity = fn():call('getWaterCapacity'):div(1000):fluid(), + water_needed = fn():call('getWaterNeeded'):div(1000):fluid(), + steam_capacity = fn():call('getSteamCapacity'):div(1000):fluid(), + steam_needed = fn():call('getSteamNeeded'):div(1000):fluid(), + }, + fuel = { + tritium_capacity = fn():call('getTritiumCapacity'):div(1000):fluid(), + tritium_needed = fn():call('getTritiumNeeded'):div(1000):fluid(), + deuterium_capacity = fn():call('getDeuteriumCapacity'):div(1000):fluid(), + deuterium_needed = fn():call('getDeuteriumNeeded'):div(1000):fluid(), + dt_fuel_capacity = fn():call('getDTFuelCapacity'):div(1000):fluid(), + dt_fuel_needed = fn():call('getDTFuelNeeded'):div(1000):fluid(), + }, + formation = { + formed = fn():call('isFormed'):toFlag(), + height = fn():call('getHeight'):with('unit', 'm'), + length = fn():call('getLength'):with('unit', 'm'), + width = fn():call('getWidth'):with('unit', 'm'), + active_cooled_logic = fn():call('isActiveCooledLogic'):toFlag(), + } + } end return FusionReactorInputAdapter \ No newline at end of file diff --git a/src/telem/lib/input/mekanism/InductionMatrixInputAdapter.lua b/src/telem/lib/input/mekanism/InductionMatrixInputAdapter.lua index 951a46f..ccb3962 100644 --- a/src/telem/lib/input/mekanism/InductionMatrixInputAdapter.lua +++ b/src/telem/lib/input/mekanism/InductionMatrixInputAdapter.lua @@ -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 InductionMatrixInputAdapter = o.class(InputAdapter) +local InductionMatrixInputAdapter = o.class(BaseMekanismInputAdapter) InductionMatrixInputAdapter.type = 'InductionMatrixInputAdapter' function InductionMatrixInputAdapter:constructor (peripheralName, categories) - self:super('constructor') + self:super('constructor', peripheralName) -- TODO this will be a configurable feature later self.prefix = 'mekinduction:' @@ -29,64 +28,36 @@ function InductionMatrixInputAdapter:constructor (peripheralName, categories) self.categories = categories end - -- boot components - self:setBoot(function () - self.components = {} - - self:addComponentByPeripheralID(peripheralName) - end)() -end - -function InductionMatrixInputAdapter:read () - self:boot() - - local source, induction = 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 .. 'energy_filled_percentage', value = induction.getEnergyFilledPercentage(), unit = nil, source = source }) - metrics:insert(Metric{ name = self.prefix .. 'energy_input', value = mekanismEnergyHelper.joulesToFE(induction.getLastInput()), unit = 'FE/t', source = source }) - metrics:insert(Metric{ name = self.prefix .. 'energy_output', value = mekanismEnergyHelper.joulesToFE(induction.getLastOutput()), unit = 'FE/t', source = source }) - metrics:insert(Metric{ name = self.prefix .. 'energy_transfer_cap', value = mekanismEnergyHelper.joulesToFE(induction.getTransferCap()), unit = 'FE/t', source = source }) - - -- some further production metrics - elseif v == 'advanced' then - metrics:insert(Metric{ name = self.prefix .. 'comparator_level', value = induction.getComparatorLevel(), unit = nil, source = source }) - - elseif v == 'energy' then - metrics:insert(Metric{ name = self.prefix .. 'energy', value = mekanismEnergyHelper.joulesToFE(induction.getEnergy()), unit = 'FE', source = source }) - metrics:insert(Metric{ name = self.prefix .. 'max_energy', value = mekanismEnergyHelper.joulesToFE(induction.getMaxEnergy()), unit = 'FE', source = source }) - metrics:insert(Metric{ name = self.prefix .. 'energy_needed', value = mekanismEnergyHelper.joulesToFE(induction.getEnergyNeeded()), unit = 'FE', source = source }) - - -- measurements based on the multiblock structure itself - elseif v == 'formation' then - metrics:insert(Metric{ name = self.prefix .. 'formed', value = (induction.isFormed() and 1 or 0), unit = nil, source = source }) - metrics:insert(Metric{ name = self.prefix .. 'height', value = induction.getHeight(), unit = 'm', source = source }) - metrics:insert(Metric{ name = self.prefix .. 'length', value = induction.getLength(), unit = 'm', source = source }) - metrics:insert(Metric{ name = self.prefix .. 'width', value = induction.getWidth(), unit = 'm', source = source }) - metrics:insert(Metric{ name = self.prefix .. 'installed_cells', value = induction.getInstalledCells(), unit = nil, source = source }) - metrics:insert(Metric{ name = self.prefix .. 'installed_providers', value = induction.getInstalledProviders(), unit = nil, source = source }) - end - - loaded[v] = true - - -- not sure if these are useful, but they return types which are not Metric compatible, RIP - -- induction.getInputItem() - -- induction.getOutputItem() - -- induction.getMaxPos() - -- induction.getMinPos() - end + self.queries = { + basic = { + energy_filled_percentage = fn():call('getEnergyFilledPercentage'), + energy_input = fn():call('getLastInput'):joulesToFE():energyRate(), + energy_output = fn():call('getLastOutput'):joulesToFE():energyRate(), + energy_transfer_cap = fn():call('getTransferCap'):joulesToFE():energyRate() + }, + advanced = { + comparator_level = fn():call('getComparatorLevel') + }, + energy = { + energy = fn():call('getEnergy'):joulesToFE():energy(), + max_energy = fn():call('getMaxEnergy'):joulesToFE():energy(), + energy_needed = fn():call('getEnergyNeeded'):joulesToFE():energy() + }, + formation = { + formed = fn():call('isFormed'):toFlag(), + height = fn():call('getHeight'):with('unit', 'm'), + length = fn():call('getLength'):with('unit', 'm'), + width = fn():call('getWidth'):with('unit', 'm'), + installed_cells = fn():call('getInstalledCells'), + installed_providers = fn():call('getInstalledProviders') + } + } - return metrics + -- not sure if these are useful, but they return types which are not Metric compatible, RIP + -- induction.getInputItem() + -- induction.getOutputItem() + -- induction.getMaxPos() + -- induction.getMinPos() end return InductionMatrixInputAdapter \ No newline at end of file diff --git a/src/telem/lib/input/mekanism/IndustrialTurbineInputAdapter.lua b/src/telem/lib/input/mekanism/IndustrialTurbineInputAdapter.lua index bdc24ca..eb157f1 100644 --- a/src/telem/lib/input/mekanism/IndustrialTurbineInputAdapter.lua +++ b/src/telem/lib/input/mekanism/IndustrialTurbineInputAdapter.lua @@ -1,21 +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 IndustrialTurbineInputAdapter = o.class(InputAdapter) +local IndustrialTurbineInputAdapter = o.class(BaseMekanismInputAdapter) IndustrialTurbineInputAdapter.type = 'IndustrialTurbineInputAdapter' -local DUMPING_MODES = { - IDLE = 1, - DUMPING_EXCESS = 2, - DUMPING = 3, -} - function IndustrialTurbineInputAdapter:constructor (peripheralName, categories) - self:super('constructor') + self:super('constructor', peripheralName) -- TODO this will be a configurable feature later self.prefix = 'mekturbine:' @@ -36,75 +29,43 @@ function IndustrialTurbineInputAdapter:constructor (peripheralName, categories) self.categories = categories end - -- boot components - self:setBoot(function () - self.components = {} - - self:addComponentByPeripheralID(peripheralName) - end)() -end - -function IndustrialTurbineInputAdapter:read () - self:boot() - - local source, turbine = 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 .. 'energy_filled_percentage', value = turbine.getEnergyFilledPercentage(), unit = nil, source = source }) - metrics:insert(Metric{ name = self.prefix .. 'energy_production_rate', value = mekanismEnergyHelper.joulesToFE(turbine.getProductionRate()), unit = 'FE/t', source = source }) - metrics:insert(Metric{ name = self.prefix .. 'energy_max_production', value = mekanismEnergyHelper.joulesToFE(turbine.getMaxProduction()), unit = 'FE/t', source = source }) - metrics:insert(Metric{ name = self.prefix .. 'steam_filled_percentage', value = turbine.getSteamFilledPercentage(), unit = nil, source = source }) - - -- some further production metrics - elseif v == 'advanced' then - metrics:insert(Metric{ name = self.prefix .. 'comparator_level', value = turbine.getComparatorLevel(), unit = nil, source = source }) - metrics:insert(Metric{ name = self.prefix .. 'dumping_mode', value = DUMPING_MODES[turbine.getDumpingMode()], unit = nil, source = source }) - metrics:insert(Metric{ name = self.prefix .. 'flow_rate', value = turbine.getFlowRate() / 1000, unit = 'B/t', source = source }) - metrics:insert(Metric{ name = self.prefix .. 'max_flow_rate', value = turbine.getMaxFlowRate() / 1000, unit = 'B/t', source = source }) - - elseif v == 'energy' then - metrics:insert(Metric{ name = self.prefix .. 'energy', value = mekanismEnergyHelper.joulesToFE(turbine.getEnergy()), unit = 'FE', source = source }) - metrics:insert(Metric{ name = self.prefix .. 'max_energy', value = mekanismEnergyHelper.joulesToFE(turbine.getMaxEnergy()), unit = 'FE', source = source }) - metrics:insert(Metric{ name = self.prefix .. 'energy_needed', value = mekanismEnergyHelper.joulesToFE(turbine.getEnergyNeeded()), unit = 'FE', source = source }) - - elseif v == 'steam' then - metrics:insert(Metric{ name = self.prefix .. 'steam_input_rate', value = turbine.getLastSteamInputRate() / 1000, unit = 'B/t', source = source }) - metrics:insert(Metric{ name = self.prefix .. 'steam', value = turbine.getSteam().amount / 1000, unit = 'B', source = source }) - metrics:insert(Metric{ name = self.prefix .. 'steam_capacity', value = turbine.getSteamCapacity() / 1000, unit = 'B', source = source }) - metrics:insert(Metric{ name = self.prefix .. 'steam_needed', value = turbine.getSteamNeeded() / 1000, unit = 'B', source = source }) - - -- measurements based on the multiblock structure itself - elseif v == 'formation' then - metrics:insert(Metric{ name = self.prefix .. 'formed', value = (turbine.isFormed() and 1 or 0), unit = nil, source = source }) - metrics:insert(Metric{ name = self.prefix .. 'height', value = turbine.getHeight(), unit = 'm', source = source }) - metrics:insert(Metric{ name = self.prefix .. 'length', value = turbine.getLength(), unit = 'm', source = source }) - metrics:insert(Metric{ name = self.prefix .. 'width', value = turbine.getWidth(), unit = 'm', source = source }) - metrics:insert(Metric{ name = self.prefix .. 'blades', value = turbine.getBlades(), unit = nil, source = source }) - metrics:insert(Metric{ name = self.prefix .. 'coils', value = turbine.getCoils(), unit = nil, source = source }) - metrics:insert(Metric{ name = self.prefix .. 'condensers', value = turbine.getCondensers(), unit = nil, source = source }) - metrics:insert(Metric{ name = self.prefix .. 'dispersers', value = turbine.getDispersers(), unit = nil, source = source }) - metrics:insert(Metric{ name = self.prefix .. 'vents', value = turbine.getVents(), unit = nil, source = source }) - metrics:insert(Metric{ name = self.prefix .. 'max_water_output', value = turbine.getMaxWaterOutput() / 1000, unit = 'B/t', source = source }) - end - - loaded[v] = true - - -- not sure if these are useful, but they return types which are not Metric compatible, RIP - -- turbine.getMaxPos(), - -- turbine.getMinPos(), - end - - return metrics + self.queries = { + basic = { + energy_filled_percentage = fn():call('getEnergyFilledPercentage'), + energy_production_rate = fn():call('getProductionRate'):joulesToFE():energyRate(), + energy_max_production = fn():call('getMaxProduction'):joulesToFE():energyRate(), + steam_filled_percentage = fn():call('getSteamFilledPercentage'), + }, + advanced = { + comparator_level = fn():call('getComparatorLevel'), + dumping_mode = fn():call('getDumpingMode'):toLookup({ IDLE = 1, DUMPING_EXCESS = 2, DUMPING = 3 }), + flow_rate = fn():call('getFlowRate'):div(1000):fluidRate(), + max_flow_rate = fn():call('getMaxFlowRate'):div(1000):fluidRate(), + }, + energy = { + energy = fn():call('getEnergy'):joulesToFE():energy(), + max_energy = fn():call('getMaxEnergy'):joulesToFE():energy(), + energy_needed = fn():call('getEnergyNeeded'):joulesToFE():energy(), + }, + steam = { + steam_input_rate = fn():call('getLastSteamInputRate'):div(1000):fluidRate(), + steam = fn():call('getSteam'):get('amount'):div(1000):fluid(), + steam_capacity = fn():call('getSteamCapacity'):div(1000):fluid(), + steam_needed = fn():call('getSteamNeeded'):div(1000):fluid(), + }, + formation = { + formed = fn():call('isFormed'):toFlag(), + height = fn():call('getHeight'):with('unit', 'm'), + length = fn():call('getLength'):with('unit', 'm'), + width = fn():call('getWidth'):with('unit', 'm'), + blades = fn():call('getBlades'), + coils = fn():call('getCoils'), + condensers = fn():call('getCondensers'), + dispersers = fn():call('getDispersers'), + vents = fn():call('getVents'), + max_water_output = fn():call('getMaxWaterOutput'):div(1000):fluidRate(), + }, + } end return IndustrialTurbineInputAdapter \ No newline at end of file diff --git a/src/telem/vendor/fluent-entrypoint.lua b/src/telem/vendor/fluent-entrypoint.lua new file mode 100644 index 0000000..c34d043 --- /dev/null +++ b/src/telem/vendor/fluent-entrypoint.lua @@ -0,0 +1,70 @@ +---@class cyberbit.Fluent +local Fluent = require 'fluent' + +--- Multiply the value by a given multiplier. +---@param multiplier number +function Fluent:mult (multiplier) + return self:_enqueue(function (this) + this.value = this.value * multiplier + end) +end + +--- Divide the value by a given divisor. +---@param divisor number +function Fluent:div (divisor) + return self:_enqueue(function (this) + this.value = this.value / divisor + end) +end + +--- Convert the value from Mekanism joules to Forge Energy/RF. +function Fluent:joulesToFE () + if not mekanismEnergyHelper then + error('mekanismEnergyHelper is not available') + end + + return self:_enqueue(function (this) + this.value = mekanismEnergyHelper.joulesToFE(this.value) + end) +end + +--- Set unit to fluid unit, 'B'. +function Fluent:fluid() + return self:with('unit', 'B') +end + +--- Set unit to fluid rate unit, 'B/t'. +function Fluent:fluidRate() + return self:with('unit', 'B/t') +end + +--- Set unit to temperature unit, 'K'. +function Fluent:temp() + return self:with('unit', 'K') +end + +--- Set unit to energy unit, 'FE'. +function Fluent:energy() + return self:with('unit', 'FE') +end + +--- Set unit to energy rate unit, 'FE/t'. +function Fluent:energyRate() + return self:with('unit', 'FE/t') +end + +--- Convert to format suitable for a Metric contstructor. +function Fluent:metricable() + return self:_enqueue(function (this) + local value = this.value + + this.value = { + name = this.params.name, + unit = this.params.unit, + source = this.params.source, + value = value, + } + end) +end + +return Fluent \ No newline at end of file diff --git a/src/telem/vendor/init.lua b/src/telem/vendor/init.lua index 07aa5ca..7764eef 100644 --- a/src/telem/vendor/init.lua +++ b/src/telem/vendor/init.lua @@ -1,6 +1,6 @@ -- Telem Vendor Loader by cyberbit -- MIT License --- Version 0.7.0 +-- Version 0.7.1 -- Submodules are copyright of their respective authors. For licensing, see https://github.com/cyberbit/telem/blob/main/LICENSE if package.path:find('telem/vendor') == nil then package.path = package.path .. ';telem/vendor/?;telem/vendor/?.lua;telem/vendor/?/init.lua' end @@ -9,7 +9,7 @@ local ecnet2 = require 'ecnet2' local random = require 'ccryptolib.random' local plotter = require 'plotter' local lualzw = require 'lualzw' -local fluent = require 'fluent' +local fluent = require 'fluent-entrypoint' return { ccryptolib = {