Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Script to control get data from a energy Detector in minecraft and output it to a control station over a wireless modem
- -- This script is designed to be run on a computer in the game Minecraft, using the ComputerCraft mod.
- -- AUTHOR: JAKOB MEYER
- ----------------------
- -- GLOBAL VARIABLES --
- ----------------------
- local configured = false
- local config
- local pwr
- local modem
- local pointName
- local energyCubes
- local energyStorage
- local timeout = 3
- local inf = math.huge
- --------------------
- -- UTIL FUNCTIONS --
- --------------------
- function split(str, sep)
- if sep == nil then
- sep = "%s"
- end
- local t = {}
- for token in string.gmatch(str, "([^" .. sep .. "]+)") do
- table.insert(t, token)
- end
- return t
- end
- function AutodetectMultiple(typelist)
- local peri = {}
- local periCount = 0
- for _, name in ipairs(peripheral.getNames()) do
- local periType = peripheral.getType(name)
- local isInList = false
- for _, typ in ipairs(typelist) do
- if periType == typ then
- isInList = true
- break
- end
- end
- print("is in List:" .. tostring(isInList) .. " Name: " .. name .. " Type: " .. periType)
- if isInList then
- periCount = periCount + 1
- peri[periCount] = name
- end
- end
- return peri
- end
- function AutodetectOne(type)
- local mult = AutodetectMultiple(type)
- if #mult == 1 then
- return AutodetectMultiple({type})[1]
- end
- if #mult > 1 then
- print("Multiple " .. type .. " found. Please specify one:")
- for i=1, #mult do
- print(i .. ": " .. mult[i])
- end
- local event, key = os.pullEvent("key")
- if key-48 >= 1 and key-48 <= #mult then
- return mult[key-48]
- else
- print("Invalid input.")
- return AutodetectOne(type)
- end
- end
- return AutodetectMultiple({type})[1]
- end
- ----------------------------
- -- CONFIGURATION FUNCTION --
- ----------------------------
- function Configure()
- print("starting config program")
- -- check if config file exists, ask if user wants to use it or delete it
- if fs.exists("config") then
- print("Config file found. Use it? (y/n), default: y")
- local event, key = os.pullEvent("key")
- if key == keys.n then
- print("deleting config file")
- fs.delete("config")
- end
- end
- -- create default config file if no config file exists
- if not fs.exists("config") then
- print("creating config file with default values")
- local config = {
- pointName = os.getComputerLabel() or "PLEASE ENTER NAME",
- pwrPos = "",
- modemPos = "",
- -- TYPE:
- -- 1: consumer, 10: consumer with Buffer,
- -- 2: producer, 20: producer with Buffer,
- -- 0: storage(In+Out), 3: none
- type = 1,
- priority = 3,
- transferRateLimit = inf,
- energyCubes = {},
- }
- local configFile = fs.open("config", "w")
- configFile.write(textutils.serialize(config))
- configFile.close()
- end
- local configFile = fs.open("config", "r")
- local configData = textutils.unserialize(configFile.readAll())
- configFile.close()
- print("Config file found. Loading current config data")
- -- NAME
- sleep(0.5)
- term.clear()
- term.setCursorPos(1, 1)
- print("Please enter a name for this power Point (" .. configData.pointName .. "):")
- local name = read()
- if name ~= "" then
- configData.pointName = name
- end
- -- TYPE
- term.clear()
- term.setCursorPos(1, 1)
- print("Please enter the type of this power point (" .. configData.type .. "):")
- print("1: consumer, 10: consumer with Buffer \n2: producer, 20: producer with Buffer \n0: storage(In+Out), 3: none")
- local type = read()
- if type ~= "" then
- configData.type = tonumber(type)
- end
- -- PRIORITY
- term.clear()
- term.setCursorPos(1, 1)
- print("Please enter the priority of this power point (" .. configData.priority .. ")")
- print("0: shutdown, \n1: very low, \n2: low, \n3: medium, \n4: high, \n5: very high")
- local priority = read()
- if priority ~= "" then
- configData.priority = tonumber(priority)
- end
- --TRANSFER RATE LIMIT
- term.clear()
- term.setCursorPos(1, 1)
- print("Please enter the transfer rate limit of this power point (" .. configData.transferRateLimit .. "):")
- local transferRateLimit = read()
- if transferRateLimit ~= "" then
- configData.transferRateLimit = tonumber(transferRateLimit)
- end
- -- AUTOMATIC DETECTION
- term.clear()
- term.setCursorPos(1, 1)
- print("Do you want to use auto detect for the peripheral? (y/n) (default: y)")
- local event, key = os.pullEvent("key")
- if key == keys.n then
- -- MANUAL
- -- ENERGY DETECTOR POSITION
- term.clear()
- term.setCursorPos(1, 1)
- print("Please enter the position/side of the energy detector (" .. configData.pwrPos .. "):")
- local pwrPos = read()
- if pwrPos ~= "" then
- configData.pwrPos = pwrPos
- end
- -- MODEM POSITION
- term.clear()
- term.setCursorPos(1, 1)
- print("Please enter the position/side of the modem (" .. configData.modemPos .. "):")
- local modemPos = read()
- if modemPos ~= "" then
- configData.modemPos = modemPos
- end
- -- ENERGY CUBES
- term.clear()
- term.setCursorPos(1, 1)
- print("Please enter the names/titles of the energy cubes. Seperate with spaces \n(default: autodetect):")
- local energyCubePos = read()
- if energyCubePos ~= "" then
- configData.energyCubes = split(energyCubePos, " ")
- else
- local typelist = {"energyCube", "basicEnergyCube", "advancedEnergyCube", "eliteEnergyCube", "ultimateEnergyCube", "creativeEnergyCube"}
- local periList = AutodetectMultiple(typelist)
- configData.energyCubes = periList
- end
- else
- -- AUTOMATIC
- -- Energy Detector
- local pwrPos = AutodetectOne("energyDetector")
- if pwrPos then
- configData.pwrPos = pwrPos
- else
- print("No energy detector found")
- sleep(5)
- end
- -- Modem
- local modemPos = AutodetectOne("modem")
- if modemPos then
- configData.modemPos = modemPos
- else
- print("No modem found")
- sleep(5)
- end
- -- Energy Cubes
- local typelist = {"energyCube", "basicEnergyCube", "advancedEnergyCube", "eliteEnergyCube", "ultimateEnergyCube", "creativeEnergyCube"}
- local periList = AutodetectMultiple(typelist)
- configData.energyCubes = periList
- end
- -- summary of the config
- term.clear()
- term.setCursorPos(1, 1)
- print("Summary of the config:")
- print("Name: " .. configData.pointName)
- print("Type: " .. configData.type)
- print("Priority: " .. configData.priority)
- print("Transfer Rate Limit: " .. configData.transferRateLimit)
- print("Energy Detector Position: " .. configData.pwrPos)
- print("Modem Position: " .. configData.modemPos)
- print("Energy Cubes: " .. table.concat(configData.energyCubes, ", "))
- print("Do you want to save the config? (y/n) (default: y)")
- local event, key = os.pullEvent("key")
- if key == keys.n then
- print("Config not saved")
- Configure()
- return
- else
- -- save config file
- local configFile = fs.open("config", "w")
- configFile.write(textutils.serialize(configData))
- configFile.close()
- print("Config saved")
- end
- configured = true
- end
- -----------------------
- -- RUNTIME FUNCTIONS --
- -----------------------
- function setLimit(limit)
- pwr.setTransferRateLimit(limit)
- end
- function checkTransferRate()
- local currentRate = pwr.getTransferRate()
- return currentRate
- end
- function checkTransferRateLimit()
- local currentLimit = pwr.getTransferRateLimit()
- return currentLimit
- end
- function getEnergy()
- if energyStorage then
- local energyJoules = 0
- for i=1, #energyCubes do
- energyJoules = energyJoules + energyCubes[i].getEnergy()
- end
- return energyJoules * 0.4
- else
- return 0
- end
- end
- function getMaxEnergy()
- if energyStorage then
- local maxEnergyJoules = 0
- for i=1, #energyCubes do
- maxEnergyJoules = maxEnergyJoules + energyCubes[i].getMaxEnergy()
- end
- return maxEnergyJoules * 0.4
- else
- return 0
- end
- end
- -------------------------
- -- DEVICE REGISTRATION --
- -------------------------
- function registerPoint()
- local deviceName = config.pointName
- local pointType = config.type
- local rate = checkTransferRate()
- local limit = checkTransferRateLimit()
- local priority = config.priority
- local storageAmount = getEnergy()
- local maxStorageAmount = getMaxEnergy()
- modem.transmit(101, 100, {"registerPoint", deviceName = deviceName, type=pointType, rate=rate, limit=limit, priority=priority,storageAmount=storageAmount, maxStorageAmount=maxStorageAmount})
- print("Sending registration: " .. deviceName .. " with type: " .. pointType .. " rate: " .. rate .. " limit: " .. limit .. " priority: " .. priority .. "storageAmount: " .. storageAmount .. " maxStorageAmount: " .. maxStorageAmount)
- local timer = os.startTimer(timeout) -- wait for 5 seconds for the confirmation
- local registered = false
- local timeoutet = false
- repeat
- local event, side, channel, replyChannel, message = os.pullEvent()
- if event == "modem_message" then
- if channel == 100 and type(message) and message[1] == "registered" then
- os.cancelTimer(timer)
- timer = os.startTimer(timeout)
- if message[2] == config.pointName and message[3] == config.type and message[4] == config.priority then
- print("Received register confirmation: " .. message[2])
- registered = true
- else
- modem.transmit(101, 100, {"registerPoint", deviceName = deviceName, type=pointType, rate=rate, limit=limit, priority=priority,storageAmount=storageAmount, maxStorageAmount=maxStorageAmount})
- print("Resending registration: " .. deviceName .. " with type: " .. pointType .. " rate: " .. rate .. " limit: " .. limit .. " priority: " .. priority .. "storageAmount: " .. storageAmount .. " maxStorageAmount: " .. maxStorageAmount)
- end
- end
- elseif event == "timer" then
- print("Timeout waiting for register confirmation")
- timeoutet = true
- end
- until registered == true or timeoutet == true
- end
- ------------------
- -- STARTUP CODE --
- ------------------
- if fs.exists("config") then
- local configFile = fs.open("config", "r")
- config = textutils.unserialize(configFile.readAll())
- configFile.close()
- else
- print("Config file not found")
- Configure()
- end
- local configFile = fs.open("config", "r")
- config = textutils.unserialize(configFile.readAll())
- configFile.close()
- pwr = peripheral.wrap(config.pwrPos)
- modem = peripheral.wrap(config.modemPos)
- pointName = config.pointName
- energyCubes = {}
- energyStorage = false
- if config.energyCubes ~= {} then
- energyStorage = true
- for i= 1, #config.energyCubes do
- energyCubes[i] = peripheral.wrap(config.energyCubes[i])
- end
- end
- modem.open(537) -- channel for sending data to control station
- modem.open(538) --channel for receiving commadns
- modem.open(100) -- listen for register command from control station
- modem.open(101) -- Answer to register command from control station
- ------------------
- -- RUNTIME LOOP --
- ------------------
- --Exptected message format:
- -- {pointName, "getTransferRate"}
- -- {pointName, "getTransferRateLimit"}
- -- {pointName, "setLimit", limit}
- -- {pointName, "getEnergy"}
- -- {pointName, "getMaxEnergy"}
- while true do
- -- check for messages from the control station
- local event, side, channel, replyChannel, message = os.pullEvent("modem_message")
- if channel == 538 and type(message) and message[1] == pointName then
- --getTransferRate
- if message[2] == "getTransferRate" then
- local currentRate = checkTransferRate()
- modem.transmit(537, 0, {pointName, currentRate})
- print("Sending transfer rate: " .. currentRate)
- --getTransferRateLimit
- elseif message[2] == "getTransferRateLimit" then
- local currentLimit = checkTransferRateLimit()
- modem.transmit(537, 0, {pointName, currentLimit})
- print("Sending transfer rate limit: " .. currentLimit)
- --setLimit
- elseif message[2] == "setLimit" then
- local limit = tonumber(message[3])
- if limit then
- setLimit(limit)
- modem.transmit(537, 0, {pointName, limit})
- else
- modem.transmit(537, 0, {pointName, "400"})
- end
- --getEnergy
- elseif message[2] == "getEnergy" then
- local energy = getEnergy()
- modem.transmit(537, 0, {pointName, energy})
- print("Sending current energy storage: " .. energy)
- elseif message[2] == "getMaxEnergy" then
- local maxEnergy = getMaxEnergy()
- modem.transmit(537, 0, {pointName, maxEnergy})
- print("Sending max energy storage: " .. maxEnergy)
- end
- elseif channel == 100 and type(message) and message[1] == "registerPoints" and message[2] =="ALL" then
- -- register all points
- print("ControlStation requested registering all points")
- registerPoint()
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement