diff --git a/configuration/descriptions.lua b/configuration/descriptions.lua index 043d27a..0491959 100644 --- a/configuration/descriptions.lua +++ b/configuration/descriptions.lua @@ -1,7 +1,7 @@ local descriptions = { hud = "Overlays a HUD on your screen. Each AR Glass can be configured independantly. X and Y resolutions are the rendering resolution of the game window. Scale is GUI Scale: 1 = Small, 2 = Normal, 3 = Large, 4-10 = Auto", server = "Updates all data and handles communication between other servers. Required for most modules to work.", - powerControl = "Emits redstone when power levels are below a certain amount. Values are set as as a percentage of the battery, 0.00 - 1.00.", + powerControl = "Emits redstone when power levels are below a certain amount. Values are set as as a percentage of the battery, 0 - 100 %. You can change the redstone mode, Normal: redstone 15 when reaches energy level. Inverted: Redstone 0 when reaches energy level.", machineDisplay = "Displays GregTech machine information on the screen.", infusion = "Automatically infuses items when it can. Should have it's own computer and run attached to an ME subsystem. Doesn't require the server module to be running. For more information on how to set the altar up, see the README file on github.", autostocker = "Automatically stocks items to configured levels.", diff --git a/modules/tools/powerControl.lua b/modules/tools/powerControl.lua index fb257b2..4e637c8 100644 --- a/modules/tools/powerControl.lua +++ b/modules/tools/powerControl.lua @@ -1,51 +1,73 @@ local component = require("component") local serialization = require("serialization") -local states = require("server.entities.states") +local states = require("server.entities.states") local powerControl = {} -local powerControlData = {} +local powerControlData = { + enableLevel = 20, -- Default activation at 20% + disableLevel = 80, -- Default deactivation at 80% + signalType = "active_low", + address = "None" +} local redstone = nil -local enableLevel = 0 -local disableLevel = 0 - +local checkingInterval = 60 +local counter = checkingInterval -local function save(data) +local function save() local file = io.open("/home/NIDAS/settings/powerControlData", "w") - enableLevel = tonumber(powerControlData.enableLevel) - disableLevel = tonumber(powerControlData.disableLevel) - if enableLevel ~= nil and disableLevel ~= nil and powerControlData.address ~= nil then - file:write(serialization.serialize(powerControlData)) - os.sleep() - file:close() + if not file then return end + + powerControlData.enableLevel = math.min(math.max(tonumber(powerControlData.enableLevel) or 20, 0), 100) + powerControlData.disableLevel = math.min(math.max(tonumber(powerControlData.disableLevel) or 80, 0), 100) + + if powerControlData.enableLevel >= powerControlData.disableLevel then + powerControlData.enableLevel, powerControlData.disableLevel = 20, 80 end + + file:write(serialization.serialize(powerControlData)) + file:close() end local function load() local file = io.open("/home/NIDAS/settings/powerControlData", "r") if file then - powerControlData = serialization.unserialize(file:read("*a")) or {} - if powerControlData == nil then powerControlData = {} end - if powerControlData.address then - if powerControlData.address ~= "None" then redstone = component.proxy(component.get(powerControlData.address)) else - redstone = nil - end - enableLevel = tonumber(powerControlData.enableLevel) - disableLevel = tonumber(powerControlData.disableLevel) - end + local data = serialization.unserialize(file:read("*a")) or {} file:close() + + powerControlData = { + enableLevel = data.enableLevel or 20, + disableLevel = data.disableLevel or 80, + address = data.address or "None", + signalType = data.signalType or "active_low" + } + + if powerControlData.address ~= "None" then + redstone = component.proxy(component.get(powerControlData.address)) + end end end -local function getPercentage(data) - return data.storedEU / data.EUCapacity -end +local function setRedstoneState(enable) + if not redstone then return end + + local signal = 0 + if enable then + signal = (powerControlData.signalType == "active_high") and 15 or 0 + else + signal = (powerControlData.signalType == "active_high") and 0 or 15 + end -local function disengage() - redstone.setOutput({0, 0, 0, 0, 0, 0}) + for side = 0, 5 do + redstone.setOutput(side, signal) + end end -local function engage() - redstone.setOutput({15, 15, 15, 15, 15, 15}) + +local function getPercentage(data) + if not data or not data.storedEU or not data.EUCapacity or data.EUCapacity == 0 then + return 0 + end + return (data.storedEU / data.EUCapacity) * 100 end local refresh = nil @@ -58,6 +80,7 @@ local function changeRedstone(redstoneAddress, data) redstone = component.proxy(component.get(redstoneAddress)) powerControlData.address = redstoneAddress end + save() local x, y, gui, graphics, renderer, page = table.unpack(data) renderer.removeObject(currentConfigWindow) refresh(x, y, gui, graphics, renderer, page) @@ -67,22 +90,60 @@ function powerControl.configure(x, y, gui, graphics, renderer, page) local renderingData = {x, y, gui, graphics, renderer, page} graphics.context().gpu.setActiveBuffer(page) graphics.text(3, 5, "Redstone I/O:") + local onActivation = {} for address, componentType in component.list() do if componentType == "redstone" then - local displayName = address - table.insert(onActivation, {displayName = displayName, value = changeRedstone, args = {address, renderingData}}) + table.insert(onActivation, {displayName = address, value = changeRedstone, args = {address, renderingData}}) end end table.insert(onActivation, {displayName = "None", value = changeRedstone, args = {"None", renderingData}}) + + currentConfigWindow = { + gui.smallButton(x+15, y+2, powerControlData.address:sub(1,8) or "None", gui.selectionBox, {x+16, y+2, onActivation}) + } + + local function toggleRedstoneMode() + if powerControlData.signalType == "active_low" then + powerControlData.signalType = "active_high" + else + powerControlData.signalType = "active_low" + end + save() + setRedstoneState(false) + refresh(x, y, gui, graphics, renderer, page) + end + + table.insert(currentConfigWindow, gui.smallButton( + x+1, y+6, + (powerControlData.signalType == "active_low") and "Normal Mode (0=ON)" or "Inverted Mode (15=ON)", + toggleRedstoneMode + )) + local _, ySize = graphics.context().gpu.getBufferSize(page) table.insert(currentConfigWindow, gui.smallButton(x+15, y+2, powerControlData.address or "None", gui.selectionBox, {x+16, y+2, onActivation})) table.insert(currentConfigWindow, gui.bigButton(x+2, y+tonumber(ySize)-4, "Save Configuration", save)) + local attributeChangeList = { - {name = "Active Level", attribute = "enableLevel", type = "string", defaultValue = "None"}, - {name = "Disable Level", attribute = "disableLevel", type = "string", defaultValue = "None"}, + { + name = "Activate Below (%)", + attribute = "enableLevel", + type = "number", + min = 0, + max = 100, + defaultValue = 20 + }, + { + name = "Deactivate Above (%)", + attribute = "disableLevel", + type = "number", + min = 0, + max = 100, + defaultValue = 80 + } } - gui.multiAttributeList(x+3, y+3, page, currentConfigWindow, attributeChangeList, powerControlData, nil, nil) + + gui.multiAttributeList(x+3, y+3, page, currentConfigWindow, attributeChangeList, powerControlData) renderer.update() return currentConfigWindow @@ -90,23 +151,20 @@ end refresh = powerControl.configure load() -local checkingInterval = 1500 -local counter = checkingInterval +local currentRedstoneState = nil function powerControl.update(data) - if counter == checkingInterval then - if data.power ~= nil and redstone ~= nil then - if data.power.state ~= states.MISSING then - local level = getPercentage(data.power) - if powerControlData.enableLevel ~= nil and powerControlData.disableLevel ~= nil then - if level < enableLevel then - engage() - elseif level > disableLevel then - disengage() - end - end + if counter >= checkingInterval then + if data and data.power and redstone then + local percent = getPercentage(data.power) + if percent <= powerControlData.enableLevel and currentRedstoneState ~= true then + setRedstoneState(true) + currentRedstoneState = true + elseif percent >= powerControlData.disableLevel and currentRedstoneState ~= false then + setRedstoneState(false) + currentRedstoneState = false end end - counter = 1 + counter = 0 else counter = counter + 1 end