Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 57f83bd56b | |||
| 5890c68d8e | |||
| facaef5983 | |||
| 256a7ecca6 | |||
| 4f8df39b69 | |||
| e41caf713c | |||
| c80f0fed9a | |||
| 8c1048698d | |||
| 903a8baf87 | |||
| e77752efae | |||
| 4e6b83a456 | |||
| f6dd0bd669 | |||
| 06f5605e3d | |||
| 2fa9be5ebf | |||
| bf83b7495d | |||
| 293fed7dd8 | |||
| bc3b41f433 | |||
| 0822432ba8 | |||
| 9278662552 | |||
| 7e3446c71a | |||
| ed2c0049e4 | |||
| caa0d1471d | |||
| 3dff0ae98a | |||
| f32a319279 | |||
| 6fa6a024dc | |||
| a5922f5409 | |||
| ea5d127774 | |||
| 7525a331c5 | |||
| 4f1b4cc6d8 |
5
.vscode/extensions.json
vendored
Normal file
5
.vscode/extensions.json
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"jackmacwindows.vscode-computercraft"
|
||||
]
|
||||
}
|
||||
18
.vscode/settings.json
vendored
Normal file
18
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"Lua.diagnostics.globals": [
|
||||
"shell"
|
||||
],
|
||||
"Lua.workspace.library": [
|
||||
"${addons}/cc-tweaked/module/library"
|
||||
],
|
||||
"Lua.runtime.version": "Lua 5.3",
|
||||
"Lua.runtime.builtin": {
|
||||
"io": "disable",
|
||||
"os": "disable"
|
||||
},
|
||||
"Lua.workspace.checkThirdParty": false,
|
||||
"Lua.diagnostics.disable": [
|
||||
"lowercase-global",
|
||||
"need-check-nil"
|
||||
]
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
local max = 15
|
||||
local init = 3
|
||||
local rateStep = 0.04
|
||||
local smallRateStep = 0.02
|
||||
local min = 1
|
||||
|
||||
local function getValue()
|
||||
return reactor.getBurnRate() or init
|
||||
end
|
||||
|
||||
|
||||
local function stepUp()
|
||||
local value = getValue()
|
||||
if value < max then
|
||||
reactor.setBurnRate(value + rateStep)
|
||||
end
|
||||
end
|
||||
|
||||
local function slowStepDown()
|
||||
local value = getValue()
|
||||
if value > min then
|
||||
reactor.setBurnRate(value - smallRateStep)
|
||||
end
|
||||
end
|
||||
|
||||
local function slowStepUp()
|
||||
local value = getValue()
|
||||
if value < max then
|
||||
reactor.setBurnRate(value + smallRateStep)
|
||||
end
|
||||
end
|
||||
|
||||
local function stepDown()
|
||||
local value = getValue()
|
||||
if value > min then
|
||||
reactor.setBurnRate(value - rateStep)
|
||||
end
|
||||
end
|
||||
|
||||
local function startup()
|
||||
return
|
||||
end
|
||||
|
||||
local function shutdown()
|
||||
end
|
||||
local function watch()
|
||||
print("Setting Default Burn Rate to: " .. init)
|
||||
reactor.setBurnRate(init)
|
||||
end
|
||||
|
||||
local function report()
|
||||
local color = colors.black
|
||||
monitor.setBackgroundColor(color)
|
||||
value = getValue()
|
||||
|
||||
setNewLine()
|
||||
monitor.write("Burn Rate: " .. value)
|
||||
end
|
||||
return { report = report, watch = watch, stepUp = stepUp, stepDown = stepDown, slowStepDown = slowStepDown, slowStepUp = slowStepUp, startup = startup, shutdown = shutdown }
|
||||
27
consumer/main.lua
Normal file
27
consumer/main.lua
Normal file
@@ -0,0 +1,27 @@
|
||||
local kernel = require("kernel")
|
||||
local taskManager = require("task-manager")
|
||||
local monitor = require("monitor-driver")
|
||||
local data = require("disk-driver")
|
||||
local speaker = require("speaker-driver")
|
||||
|
||||
local chat = kernel.addProgram("chat")
|
||||
local gps = kernel.addProgram("gps")
|
||||
|
||||
|
||||
local function run()
|
||||
monitor.initialize()
|
||||
data.initialize()
|
||||
speaker.initialize()
|
||||
|
||||
monitor.writeLine("Starting system...")
|
||||
monitor.writeLine("System started successfully!")
|
||||
computerName = data.getRead("computer-name")
|
||||
os.setComputerLabel(computerName)
|
||||
monitor.writeLine("Computer name: " .. computerName)
|
||||
|
||||
taskManager.addProgram("Communication", chat);
|
||||
taskManager.addProgram("GPS", gps);
|
||||
taskManager.listPrograms()
|
||||
end
|
||||
|
||||
return { run = run }
|
||||
8
consumer/startup.lua
Normal file
8
consumer/startup.lua
Normal file
@@ -0,0 +1,8 @@
|
||||
|
||||
shell.execute("rm", "kernel.lua")
|
||||
shell.execute("wget", "https://git.astrocore.space/root/nova-corp/raw/branch/main/kernel.lua")
|
||||
sleep(5)
|
||||
local kernel = require("kernel")
|
||||
local main = kernel.addFolderDriver("consumer", "main")
|
||||
main.run()
|
||||
|
||||
Binary file not shown.
@@ -1,51 +0,0 @@
|
||||
local maxValue = 90
|
||||
local minValue = 80
|
||||
local minCoolant = 20
|
||||
|
||||
local function getValue()
|
||||
return (reactor.getCoolantFilledPercentage() or 1) * 100
|
||||
end
|
||||
|
||||
local function checkCoolantLevel()
|
||||
local coolantLevel = getValue()
|
||||
if coolantLevel > maxValue then
|
||||
-- Do nothing if coolant is above the max value
|
||||
elseif coolantLevel > minValue then
|
||||
-- print("Coolant approaching minimum, slowly stepping down burn rate.")
|
||||
-- burnRateDriver.slowStepDown()
|
||||
elseif coolantLevel <= minCoolant then
|
||||
print("Critical Warning: Coolant below minimum safe level! SCRAMMING reactor.")
|
||||
reactor.scram()
|
||||
elseif coolantLevel <= minValue then
|
||||
print("Warning: Coolant below minimum! Stepping down burn rate.")
|
||||
burnRateDriver.stepDown()
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local function watch()
|
||||
while true do
|
||||
checkCoolantLevel()
|
||||
sleep(0.05)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function startup()
|
||||
return
|
||||
end
|
||||
|
||||
local function shutdown()
|
||||
end
|
||||
|
||||
local function report()
|
||||
local value = getValue()
|
||||
local color = colors.black
|
||||
monitor.setBackgroundColor(color)
|
||||
|
||||
setNewLine()
|
||||
monitor.write("Coolant: " .. value .. "%")
|
||||
end
|
||||
|
||||
|
||||
return { report = report, watch = watch, startup = startup, shutdown = shutdown }
|
||||
101
disk-driver.lua
Normal file
101
disk-driver.lua
Normal file
@@ -0,0 +1,101 @@
|
||||
local diskDrive = peripheral.find("drive")
|
||||
local monitor = require("monitor-driver")
|
||||
local function getFilePath()
|
||||
if diskDrive and diskDrive.isDiskPresent() then
|
||||
local path = diskDrive.getMountPath()
|
||||
if path then
|
||||
return fs.combine(path, "data.tbl")
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local function loadData()
|
||||
local path = getFilePath()
|
||||
if path and fs.exists(path) then
|
||||
local file = fs.open(path, "r")
|
||||
local content = file.readAll()
|
||||
file.close()
|
||||
local parsed
|
||||
if content then
|
||||
parsed = textutils.unserialize(content)
|
||||
end
|
||||
return parsed or {}
|
||||
end
|
||||
return {}
|
||||
end
|
||||
|
||||
local function saveData(data)
|
||||
local path = getFilePath()
|
||||
if path then
|
||||
local file = fs.open(path, "w")
|
||||
file.write(textutils.serialize(data))
|
||||
file.close()
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function generateGuid()
|
||||
local template ='xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'
|
||||
return string.gsub(template, '[xy]', function (c)
|
||||
local v = (c == 'x') and math.random(0, 0xf) or math.random(8, 0xb)
|
||||
return string.format('%x', v)
|
||||
end)
|
||||
end
|
||||
|
||||
local function getValue(key)
|
||||
local data = loadData()
|
||||
for _, item in ipairs(data) do
|
||||
if item.Key == key then
|
||||
return item.Value
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local function updateValue(key, value)
|
||||
local data = loadData()
|
||||
for _, item in ipairs(data) do
|
||||
if item.Key == key then
|
||||
item.Value = value
|
||||
saveData(data)
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function writeValue(key, value)
|
||||
local data = loadData()
|
||||
local guid = generateGuid()
|
||||
table.insert(data, { GeneratedGuid = guid, Key = key, Value = value })
|
||||
saveData(data)
|
||||
return guid
|
||||
end
|
||||
|
||||
local function initialize()
|
||||
monitor.writeLine("Initializing Data Storage...")
|
||||
if diskDrive and diskDrive.isDiskPresent() then
|
||||
monitor.writeLine("Disk detected. Initializing data storage.")
|
||||
local path = getFilePath()
|
||||
if path and not fs.exists(path) then
|
||||
saveData({})
|
||||
end
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function getRead(key)
|
||||
local value = getValue(key)
|
||||
if value then
|
||||
return value
|
||||
end
|
||||
print("Enter value for " .. key .. ":")
|
||||
local input = read()
|
||||
writeValue(key, input)
|
||||
return input
|
||||
end
|
||||
|
||||
return { getValue = getValue, updateValue = updateValue, writeValue = writeValue, initialize = initialize, getRead = getRead }
|
||||
@@ -1,34 +0,0 @@
|
||||
|
||||
local function getValue(env)
|
||||
local value = env.getRadiation()
|
||||
print(value.radiation, value.unit)
|
||||
local stringValue = tostring(value.radiation) .. " " .. tostring(value.unit)
|
||||
return stringValue
|
||||
end
|
||||
|
||||
local function watch()
|
||||
while true do
|
||||
sleep(0.05) -- Update every tenth second
|
||||
end
|
||||
end
|
||||
|
||||
local function startup()
|
||||
end
|
||||
|
||||
local function shutdown()
|
||||
end
|
||||
|
||||
local function report()
|
||||
setNewLine()
|
||||
setNewLine()
|
||||
monitor.setBackgroundColor(colors.blue)
|
||||
monitor.write("Radiation Levels:")
|
||||
monitor.setBackgroundColor(colors.black)
|
||||
local internal = getValue(internalEnvironment)
|
||||
local external = getValue(externalEnvironment)
|
||||
setNewLine()
|
||||
monitor.write("Internal: " .. internal)
|
||||
setNewLine()
|
||||
monitor.write("External: " .. external)
|
||||
end
|
||||
return { report = report, watch = watch, startup = startup, shutdown = shutdown }
|
||||
1486
external_alarm.dfpwm
1486
external_alarm.dfpwm
File diff suppressed because one or more lines are too long
Binary file not shown.
53
kernel.lua
53
kernel.lua
@@ -1,11 +1,60 @@
|
||||
|
||||
|
||||
local function addDriver(fileName)
|
||||
local extension = ".lua"
|
||||
local fullFile = fileName .. extension
|
||||
shell.execute("rm", fullFile)
|
||||
local baseRoute = "https://git.astrocore.space/root/nova-corp/raw/branch/main/"
|
||||
shell.execute("wget", baseRoute .. fullFile)
|
||||
sleep(1)
|
||||
sleep(2)
|
||||
return require(fileName)
|
||||
end
|
||||
|
||||
return { addDriver = addDriver }
|
||||
local function addFolderDriver(folder, fileName)
|
||||
local extension = ".lua"
|
||||
local fullFile = fileName .. extension
|
||||
shell.execute("rm", fullFile)
|
||||
local baseRoute = "https://git.astrocore.space/root/nova-corp/raw/branch/main/"
|
||||
shell.execute("wget", baseRoute .. folder .. "/" .. fullFile)
|
||||
sleep(2)
|
||||
return require(fileName)
|
||||
end
|
||||
|
||||
local function addProgram(fileName)
|
||||
local extension = ".lua"
|
||||
local fullFile = fileName .. extension
|
||||
shell.execute("rm", fullFile)
|
||||
local baseRoute = "https://git.astrocore.space/root/nova-corp/raw/branch/main/"
|
||||
shell.execute("wget", baseRoute .. "programs" .. "/" .. fullFile)
|
||||
sleep(2)
|
||||
return require(fileName)
|
||||
end
|
||||
|
||||
local function addSound(fileName)
|
||||
local extension = ".dfpwm"
|
||||
local fullFile = fileName .. extension
|
||||
shell.execute("rm", fullFile)
|
||||
local baseRoute = "https://git.astrocore.space/root/nova-corp/raw/branch/main/"
|
||||
shell.execute("wget", baseRoute .. "sounds" .. "/" .. fullFile)
|
||||
sleep(2)
|
||||
return
|
||||
end
|
||||
|
||||
local function addServerHandler(fileName)
|
||||
local extension = ".lua"
|
||||
local fullFile = fileName .. extension
|
||||
shell.execute("rm", fullFile)
|
||||
local baseRoute = "https://git.astrocore.space/root/nova-corp/raw/branch/main/"
|
||||
shell.execute("wget", baseRoute .. "server" .. "/" .. fullFile)
|
||||
sleep(2)
|
||||
return require(fileName)
|
||||
end
|
||||
|
||||
|
||||
addDriver("task-manager")
|
||||
addDriver("monitor-driver")
|
||||
addDriver("disk-driver")
|
||||
addDriver("speaker-driver")
|
||||
|
||||
|
||||
return { addDriver = addDriver, addFolderDriver = addFolderDriver, addProgram = addProgram, addSound = addSound, addServerHandler = addServerHandler }
|
||||
126
main.lua
126
main.lua
@@ -1,126 +0,0 @@
|
||||
kernel = require("kernel")
|
||||
reactor = peripheral.find("fissionReactorLogicAdapter")
|
||||
turbine = peripheral.find("turbineValve")
|
||||
turbineVent = peripheral.find("turbineVent")
|
||||
monitor = peripheral.find("monitor")
|
||||
internalEnvironment = peripheral.wrap("environmentDetector_0")
|
||||
externalEnvironment = peripheral.wrap("environmentDetector_1")
|
||||
modem = peripheral.find("modem")
|
||||
controlRoomSpeakers = peripheral.find("speaker")
|
||||
|
||||
tempDriver = kernel.addDriver("temperature_driver")
|
||||
coolantDriver = kernel.addDriver("coolant_driver")
|
||||
statusDriver = kernel.addDriver("status_driver")
|
||||
turbineDriver = kernel.addDriver("turbine_driver")
|
||||
burnRateDriver = kernel.addDriver("burnrate_driver")
|
||||
environmentDriver = kernel.addDriver("environment_driver")
|
||||
speakerDriver = kernel.addDriver("speaker_driver")
|
||||
|
||||
isErrorState = false
|
||||
reactorStatus = false
|
||||
|
||||
function setNewLine()
|
||||
local x,y = monitor.getCursorPos()
|
||||
monitor.setCursorPos(1, y + 1)
|
||||
monitor.clearLine()
|
||||
end
|
||||
|
||||
local function runMonitors()
|
||||
if(reactorStatus) then
|
||||
parallel.waitForAll(
|
||||
tempDriver.watch,
|
||||
coolantDriver.watch,
|
||||
statusDriver.watch,
|
||||
turbineDriver.watch,
|
||||
burnRateDriver.watch,
|
||||
environmentDriver.watch)
|
||||
else
|
||||
end
|
||||
end
|
||||
|
||||
local function runDisplay()
|
||||
monitor.clear()
|
||||
monitor.setTextScale(1)
|
||||
while true do
|
||||
monitor.setCursorPos(1, 0)
|
||||
setNewLine()
|
||||
monitor.setBackgroundColor(colors.blue)
|
||||
monitor.write("Reactor Readings:")
|
||||
local drivers = {
|
||||
{ Label = "Status", driver = statusDriver},
|
||||
{ Label = "Temperature", driver = tempDriver },
|
||||
{ Label = "Coolant", driver = coolantDriver },
|
||||
{ Label = "Turbine", driver = turbineDriver },
|
||||
{ Label = "Burn Rate", driver = burnRateDriver },
|
||||
{ Label = "Radiation Level", driver = environmentDriver }
|
||||
}
|
||||
|
||||
|
||||
for i, item in ipairs(drivers) do
|
||||
item.driver.report()
|
||||
end
|
||||
|
||||
sleep(0.05) -- Update every tenth second
|
||||
end
|
||||
end
|
||||
|
||||
local function startup()
|
||||
parallel.waitForAll(tempDriver.startup,
|
||||
coolantDriver.startup,
|
||||
statusDriver.startup,
|
||||
turbineDriver.startup,
|
||||
burnRateDriver.startup,
|
||||
environmentDriver.startup)
|
||||
end
|
||||
|
||||
local function shutDown()
|
||||
parallel.waitForAll(tempDriver.shutDown,
|
||||
coolantDriver.shutDown,
|
||||
statusDriver.shutDown,
|
||||
turbineDriver.shutDown,
|
||||
burnRateDriver.shutDown,
|
||||
environmentDriver.shutDown)
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function runSafe()
|
||||
while not reactor do
|
||||
print("Waiting for reactor signal...")
|
||||
sleep(1)
|
||||
end
|
||||
while not turbine do
|
||||
print("Waiting for turbine signal...")
|
||||
sleep(1)
|
||||
end
|
||||
while not monitor do
|
||||
print("Waiting for monitor signal...")
|
||||
sleep(1)
|
||||
end
|
||||
|
||||
startup();
|
||||
monitor.clear();
|
||||
monitor.setBackgroundColor(colors.black)
|
||||
-- local names = peripheral.getNames()
|
||||
-- for index, value in ipairs(names) do
|
||||
-- print(index, value)
|
||||
-- read()
|
||||
-- end
|
||||
parallel.waitForAll(runMonitors, runDisplay)
|
||||
end
|
||||
|
||||
local function run()
|
||||
local success, err = pcall(runSafe)
|
||||
if not success then
|
||||
monitor.setTextColor(colors.red)
|
||||
monitor.write("Error: " .. err)
|
||||
isErrorState = true
|
||||
modem.open(500)
|
||||
modem.transmit(500, 500, "Error: " .. err)
|
||||
os.reboot()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
return { run = run }
|
||||
15
monitor-driver.lua
Normal file
15
monitor-driver.lua
Normal file
@@ -0,0 +1,15 @@
|
||||
local monitor = peripheral.find("monitor")
|
||||
|
||||
local function writeLine(text)
|
||||
monitor.write(text)
|
||||
local x, y = monitor.getCursorPos()
|
||||
monitor.setCursorPos(1, y + 1)
|
||||
end
|
||||
|
||||
local function initialize()
|
||||
monitor.clear()
|
||||
monitor.setCursorPos(1,1)
|
||||
writeLine("Initializing monitor driver...")
|
||||
end
|
||||
|
||||
return { writeLine = writeLine, initialize = initialize }
|
||||
@@ -1,32 +0,0 @@
|
||||
kernel = require("kernel")
|
||||
speakerDriver = kernel.addDriver("speaker_driver")
|
||||
local modem = peripheral.find("modem")
|
||||
local monitor = peripheral.wrap("top")
|
||||
controlRoomSpeakers = peripheral.find("speaker")
|
||||
|
||||
function setNewLine()
|
||||
local x,y = monitor.getCursorPos()
|
||||
monitor.setCursorPos(1, y + 1)
|
||||
monitor.clearLine()
|
||||
end
|
||||
|
||||
local function startup()
|
||||
speakerDriver.startup()
|
||||
speakerDriver.playTTSFile(peripheral.wrap("left"), "ELLO MATE LOVELY DAY INIT YOU GOT ANYYYY BEEEANSS AND TOAST ON YA MATE ID LOVE TO HAVE SOME BEANS N TOAST")
|
||||
speakerDriver.playTTSFile(peripheral.wrap("right"), "ELLO MATE LOVELY DAY INIT YOU GOT ANYYYY BEEEANSS AND TOAST ON YA MATE ID LOVE TO HAVE SOME BEANS N TOAST")
|
||||
end
|
||||
|
||||
local function run()
|
||||
monitor.setTextScale(0.5)
|
||||
monitor.setCursorPos(1,0)
|
||||
startup()
|
||||
while true do
|
||||
setNewLine()
|
||||
monitor.write("Checking for reactor status...")
|
||||
setNewLine()
|
||||
monitor.write("Checking main control loop...")
|
||||
sleep(2)
|
||||
end
|
||||
end
|
||||
|
||||
return { run = run }
|
||||
@@ -1,4 +0,0 @@
|
||||
local kernel = require("kernel")
|
||||
local main = kernel.addDriver("pairity_main")
|
||||
sleep(5)
|
||||
main.run()
|
||||
70
programs/chat.lua
Normal file
70
programs/chat.lua
Normal file
@@ -0,0 +1,70 @@
|
||||
local modem = peripheral.find("modem")
|
||||
local speaker = require("speaker-driver")
|
||||
local SERVER_PORT = 100
|
||||
local CLIENT_PORT = 101
|
||||
|
||||
local username = os.getComputerLabel() or ("User" .. os.getComputerID())
|
||||
|
||||
local function start()
|
||||
if modem then
|
||||
modem.open(CLIENT_PORT)
|
||||
modem.transmit(SERVER_PORT, CLIENT_PORT, { type = "join", username = username })
|
||||
end
|
||||
print("Chat program started as " .. username)
|
||||
end
|
||||
|
||||
local function stop()
|
||||
if modem then
|
||||
modem.transmit(SERVER_PORT, CLIENT_PORT, { type = "leave", username = username })
|
||||
modem.close(CLIENT_PORT)
|
||||
end
|
||||
print("Chat program stopped.")
|
||||
end
|
||||
|
||||
local function restart()
|
||||
stop()
|
||||
start()
|
||||
end
|
||||
|
||||
local function receiveLoop()
|
||||
while true do
|
||||
local event, side, channel, replyChannel, message, distance = os.pullEvent("modem_message")
|
||||
if channel == CLIENT_PORT and type(message) == "table" then
|
||||
local x, y = term.getCursorPos()
|
||||
term.setCursorPos(1, y)
|
||||
term.clearLine()
|
||||
|
||||
if message.type == "system" then
|
||||
print("[System] " .. message.content)
|
||||
speaker.play("notification")
|
||||
elseif message.type == "chat" then
|
||||
print(message.username .. ": " .. message.content)
|
||||
speaker.play("notification")
|
||||
speaker.playTTSFile(message.content)
|
||||
end
|
||||
|
||||
write("> ")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function sendLoop()
|
||||
while true do
|
||||
write("> ")
|
||||
local input = read()
|
||||
if modem then
|
||||
modem.transmit(SERVER_PORT, CLIENT_PORT, { type = "chat", username = username, content = input })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function main()
|
||||
if not modem then
|
||||
print("No modem attached")
|
||||
while true do os.pullEvent() end
|
||||
end
|
||||
|
||||
parallel.waitForAny(receiveLoop, sendLoop)
|
||||
end
|
||||
|
||||
return { start = start, stop = stop, restart = restart, main = main }
|
||||
24
programs/gps.lua
Normal file
24
programs/gps.lua
Normal file
@@ -0,0 +1,24 @@
|
||||
local function start()
|
||||
print("GPS program started.")
|
||||
end
|
||||
|
||||
local function stop()
|
||||
print("GPS program stopped.")
|
||||
end
|
||||
|
||||
local function restart()
|
||||
stop()
|
||||
start()
|
||||
end
|
||||
|
||||
local function main()
|
||||
print("Chat main loop running...")
|
||||
while true do
|
||||
local event = os.pullEvent()
|
||||
if event == "char" then
|
||||
print("GPS Char")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return { start = start, stop = stop, restart = restart, main = main }
|
||||
51
server/chat-server.lua
Normal file
51
server/chat-server.lua
Normal file
@@ -0,0 +1,51 @@
|
||||
local modem = peripheral.find("modem")
|
||||
local SERVER_PORT = 100
|
||||
local CLIENT_PORT = 101
|
||||
|
||||
local function log(msg)
|
||||
print("[Server]: " .. tostring(msg))
|
||||
end
|
||||
|
||||
local function broadcast(message)
|
||||
if modem then
|
||||
modem.transmit(CLIENT_PORT, SERVER_PORT, message)
|
||||
end
|
||||
end
|
||||
|
||||
local function handleMessage(event, side, channel, replyChannel, message, distance)
|
||||
if type(message) == "table" then
|
||||
if message.type == "join" then
|
||||
log(message.username .. " connected.")
|
||||
broadcast({ type = "system", content = message.username .. " joined the chat." })
|
||||
elseif message.type == "leave" then
|
||||
log(message.username .. " disconnected.")
|
||||
broadcast({ type = "system", content = message.username .. " left the chat." })
|
||||
elseif message.type == "chat" then
|
||||
log(message.username .. ": " .. message.content)
|
||||
broadcast({ type = "chat", username = message.username, content = message.content })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function listenLoop()
|
||||
if not modem then
|
||||
log("No modem found!")
|
||||
return
|
||||
end
|
||||
modem.open(SERVER_PORT)
|
||||
log("Listening on port " .. SERVER_PORT)
|
||||
|
||||
while true do
|
||||
local eventData = {os.pullEvent("modem_message")}
|
||||
-- event, side, channel, replyChannel, message, distance
|
||||
if eventData[3] == SERVER_PORT then
|
||||
handleMessage(table.unpack(eventData))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function main()
|
||||
parallel.waitForAll(listenLoop)
|
||||
end
|
||||
|
||||
return { main = main }
|
||||
12
server/main.lua
Normal file
12
server/main.lua
Normal file
@@ -0,0 +1,12 @@
|
||||
local kernel = require("kernel")
|
||||
local chat = kernel.addServerHandler("chat-server")
|
||||
|
||||
|
||||
local function run()
|
||||
print("Starting Server...")
|
||||
local tasks = {}
|
||||
table.insert(tasks, chat.main)
|
||||
parallel.waitForAll(table.unpack(tasks))
|
||||
end
|
||||
|
||||
return { run = run }
|
||||
7
server/startup.lua
Normal file
7
server/startup.lua
Normal file
@@ -0,0 +1,7 @@
|
||||
shell.execute("rm", "kernel.lua")
|
||||
shell.execute("wget", "https://git.astrocore.space/root/nova-corp/raw/branch/main/kernel.lua")
|
||||
sleep(5)
|
||||
local kernel = require("kernel")
|
||||
local main = kernel.addFolderDriver("server", "main")
|
||||
main.run()
|
||||
|
||||
Binary file not shown.
BIN
sounds/notification.dfpwm
Normal file
BIN
sounds/notification.dfpwm
Normal file
Binary file not shown.
98
speaker-driver.lua
Normal file
98
speaker-driver.lua
Normal file
@@ -0,0 +1,98 @@
|
||||
local speaker = peripheral.find("speaker")
|
||||
local dfpwm = require("cc.audio.dfpwm")
|
||||
local encoder = dfpwm.make_encoder()
|
||||
local decoder = dfpwm.make_decoder()
|
||||
|
||||
local sounds = {
|
||||
{name = "notification", file = "notification.dfpwm"}
|
||||
}
|
||||
|
||||
local function initialize()
|
||||
kernel = require("kernel")
|
||||
kernel.addSound("notification")
|
||||
speaker = peripheral.find("speaker")
|
||||
if not speaker then
|
||||
print("Warning: No speaker attached.")
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local function play(name)
|
||||
if not speaker then return false end
|
||||
|
||||
local filePath
|
||||
for _, sound in ipairs(sounds) do
|
||||
if sound.name == name then
|
||||
filePath = sound.file
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if not filePath then
|
||||
print("Sound '" .. name .. "' not defined.")
|
||||
return false
|
||||
end
|
||||
|
||||
if not fs.exists(filePath) then
|
||||
print("File '" .. filePath .. "' not found.")
|
||||
return false
|
||||
end
|
||||
|
||||
-- Create a new decoder for this playback to reset state
|
||||
local decoder = dfpwm.make_decoder()
|
||||
|
||||
for chunk in io.lines(filePath, 16 * 1024) do
|
||||
local buffer = decoder(chunk)
|
||||
while not speaker.playAudio(buffer, 3.0) do
|
||||
os.pullEvent("speaker_audio_empty")
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
----------------
|
||||
|
||||
local function getFileName(name)
|
||||
local extension = ".dfpwm"
|
||||
local fullFile = name .. extension
|
||||
return fullFile
|
||||
end
|
||||
|
||||
local function randomFileName()
|
||||
local name = ""
|
||||
for i = 1, 12 do
|
||||
name = name .. string.char(math.random(97, 122)) -- a–z
|
||||
end
|
||||
return name
|
||||
end
|
||||
|
||||
local function playSound(fileName)
|
||||
local fileStream = getFileName(fileName)
|
||||
local values = io.lines(fileStream, 16 * 1024)
|
||||
for input in values do
|
||||
local decoded = decoder(input)
|
||||
while not speaker.playAudio(decoded, 3.0) do
|
||||
os.pullEvent("speaker_audio_empty")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function playTTSFile(value)
|
||||
local message = textutils.urlEncode(value)
|
||||
local url = "http://api.astrocore.space/api/TextToSpeech?message=" .. message
|
||||
local response, err = http.get { url = url, binary = true }
|
||||
local name = randomFileName()
|
||||
local fileName = name .. ".dfpwm"
|
||||
|
||||
local fileData = response.readAll()
|
||||
local file = fs.open(fileName,"w")
|
||||
file.write(fileData)
|
||||
file.close()
|
||||
response.close()
|
||||
playSound(name)
|
||||
shell.execute("rm", fileName)
|
||||
end
|
||||
|
||||
return { initialize = initialize, play = play, playTTSFile = playTTSFile }
|
||||
@@ -1,130 +0,0 @@
|
||||
local dfpwm = require("cc.audio.dfpwm")
|
||||
local encoder = dfpwm.make_encoder()
|
||||
local decoder = dfpwm.make_decoder()
|
||||
local baseRoute = "https://git.astrocore.space/root/NovaCorpLLC/raw/branch/main/"
|
||||
|
||||
local function getFileName(name)
|
||||
local extension = ".dfpwm"
|
||||
local fullFile = name .. extension
|
||||
return fullFile
|
||||
end
|
||||
|
||||
local function randomFileName()
|
||||
local name = ""
|
||||
for i = 1, 12 do
|
||||
name = name .. string.char(math.random(97, 122)) -- a–z
|
||||
end
|
||||
return name
|
||||
end
|
||||
|
||||
local function playSound(speaker, fileName)
|
||||
local fileStream = getFileName(fileName)
|
||||
local values = io.lines(fileStream, 16 * 1024)
|
||||
for input in values do
|
||||
print("playing audo....")
|
||||
local decoded = decoder(input)
|
||||
while not speaker.playAudio(decoded, 3) do
|
||||
os.pullEvent("speaker_audio_empty")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function playControlRoomAlarm(speakers)
|
||||
playSound(speakers,"short_control_alarm")
|
||||
end
|
||||
|
||||
local function playExternalAlarm(speakers)
|
||||
playSound(speakers,"external_alarm")
|
||||
end
|
||||
|
||||
local function playInternalAlarm(speakers)
|
||||
playSound(speakers,"internal_alarm")
|
||||
end
|
||||
|
||||
local function playTTSFile(speakers, value)
|
||||
local message = textutils.urlEncode(value)
|
||||
local url = "http://api.astrocore.space/api/TextToSpeech?message=" .. message
|
||||
local response, err = http.get { url = url, binary = true }
|
||||
local name = randomFileName()
|
||||
local fileName = name .. ".dfpwm"
|
||||
|
||||
local fileData = response.readAll()
|
||||
local file = fs.open(fileName,"w")
|
||||
file.write(fileData)
|
||||
file.close()
|
||||
response.close()
|
||||
playSound(speakers, name)
|
||||
shell.execute("rm", fileName)
|
||||
end
|
||||
|
||||
local function createSoundFile(fileName)
|
||||
local name = getFileName(fileName)
|
||||
local fullPath = baseRoute .. name
|
||||
shell.execute("rm", name)
|
||||
local response = http.request({
|
||||
url = fullPath,
|
||||
method = "GET",
|
||||
binary = true
|
||||
})
|
||||
|
||||
|
||||
local event, url, handle
|
||||
repeat
|
||||
event, url, handle = os.pullEvent()
|
||||
if event == "http_failure" and url == fullPath then
|
||||
print("HTTP request failed for: " .. url)
|
||||
print(event)
|
||||
return nil
|
||||
end
|
||||
if event == "http_success" then
|
||||
print("Waiting for response for " .. fileName)
|
||||
end
|
||||
until event == "http_success" and url == fullPath
|
||||
print("Recieved response!")
|
||||
local fileData = handle.readAll()
|
||||
local file = fs.open(name,"w")
|
||||
|
||||
file.write(fileData)
|
||||
file.close()
|
||||
handle.close()
|
||||
end
|
||||
|
||||
|
||||
function addSoundFile(fileName)
|
||||
createSoundFile(fileName)
|
||||
end
|
||||
|
||||
local function watch()
|
||||
end
|
||||
|
||||
|
||||
local function startup()
|
||||
local sounds = {
|
||||
{ fileName = "short_control_alarm" },
|
||||
{ fileName = "external_alarm" },
|
||||
{ fileName = "internal_alarm" }
|
||||
}
|
||||
|
||||
for i, item in ipairs(sounds) do
|
||||
addSoundFile(item.fileName)
|
||||
print("Added sound file: " .. item.fileName)
|
||||
end
|
||||
end
|
||||
|
||||
local function shutdown()
|
||||
end
|
||||
|
||||
|
||||
local function report()
|
||||
end
|
||||
|
||||
return { report = report,
|
||||
watch = watch,
|
||||
startup = startup,
|
||||
shutdown = shutdown,
|
||||
playControlRoomAlarm = playControlRoomAlarm,
|
||||
addSoundFile = addSoundFile,
|
||||
playExternalAlarm = playExternalAlarm,
|
||||
playInternalAlarm = playInternalAlarm,
|
||||
playTTSFile = playTTSFile
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
speaker = peripheral.find("speaker")
|
||||
speakerDriver = kernel.addDriver("speaker_driver")
|
||||
|
||||
local function startup()
|
||||
parallel.waitForAll(speakerDriver.startup)
|
||||
end
|
||||
|
||||
local function shutDown()
|
||||
parallel.waitForAll(speakerDriver.shutDown)
|
||||
end
|
||||
|
||||
local function runSafe()
|
||||
startup()
|
||||
end
|
||||
|
||||
local function run()
|
||||
local success, err = pcall(runSafe)
|
||||
if not success then
|
||||
os.reboot()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
return { run = run }
|
||||
@@ -1,4 +0,0 @@
|
||||
local kernel = require("kernel")
|
||||
local main = kernel.addDriver("speaker_main")
|
||||
sleep(5)
|
||||
main.run()
|
||||
@@ -1,4 +0,0 @@
|
||||
local kernel = require("kernel")
|
||||
local main = kernel.addDriver("main")
|
||||
sleep(5)
|
||||
main.run()
|
||||
@@ -1,42 +0,0 @@
|
||||
|
||||
local function getValue()
|
||||
return reactor.getStatus() or false
|
||||
end
|
||||
|
||||
|
||||
local function checkStatus()
|
||||
local value = getValue()
|
||||
end
|
||||
|
||||
local function watch()
|
||||
while true do
|
||||
checkStatus()
|
||||
sleep(0.05) -- Update every tenth second
|
||||
end
|
||||
end
|
||||
|
||||
local function startup()
|
||||
reactor.setBurnRate(2)
|
||||
local status = reactor.getStatus()
|
||||
if(not status) then
|
||||
reactor.activate()
|
||||
return
|
||||
end
|
||||
|
||||
reactorStatus = reactor.getStatus()
|
||||
end
|
||||
|
||||
local function shutdown()
|
||||
reactor.setBurnRate(0)
|
||||
reactor.deactivate()
|
||||
end
|
||||
|
||||
local function report()
|
||||
local value = getValue()
|
||||
local color = colors.black
|
||||
monitor.setBackgroundColor(color)
|
||||
|
||||
setNewLine()
|
||||
monitor.write("Reactor Status: " .. tostring(value))
|
||||
end
|
||||
return { report = report, watch = watch, startup = startup, shutdown = shutdown }
|
||||
146
task-manager.lua
Normal file
146
task-manager.lua
Normal file
@@ -0,0 +1,146 @@
|
||||
local monitor = peripheral.find("monitor")
|
||||
local programs = {}
|
||||
local isRunning = false
|
||||
|
||||
|
||||
local function addProgram(name, program)
|
||||
table.insert(programs, {name = name, program = program})
|
||||
end
|
||||
|
||||
local function runProgram(programOrPath)
|
||||
local programModule
|
||||
|
||||
if type(programOrPath) == "string" then
|
||||
if fs.exists(programOrPath) then
|
||||
-- Load the file as a chunk. In Lua 5.2+ use the env parameter instead of setfenv.
|
||||
local env = _ENV or _G
|
||||
local programChunk, err = loadfile(programOrPath, "t", env)
|
||||
if not programChunk then
|
||||
print("Error loading program: " .. err)
|
||||
return false
|
||||
end
|
||||
|
||||
-- Run the chunk to get the module table
|
||||
local success, result = pcall(programChunk)
|
||||
|
||||
if not success then
|
||||
print("Error executing program file: " .. tostring(result))
|
||||
return false
|
||||
end
|
||||
programModule = result
|
||||
else
|
||||
print("Program not found: " .. programOrPath)
|
||||
return false
|
||||
end
|
||||
elseif type(programOrPath) == "table" then
|
||||
programModule = programOrPath
|
||||
else
|
||||
print("Invalid program type")
|
||||
return false
|
||||
end
|
||||
|
||||
if type(programModule) ~= "table" or not programModule.main then
|
||||
print("Error: Program must return a table with at least a 'main' function.")
|
||||
return false
|
||||
end
|
||||
|
||||
-- Setup Monitor
|
||||
local w, h = monitor.getSize()
|
||||
monitor.setBackgroundColor(colors.black)
|
||||
monitor.clear()
|
||||
|
||||
-- Draw X button
|
||||
monitor.setCursorPos(w, 1)
|
||||
monitor.setBackgroundColor(colors.red)
|
||||
monitor.setTextColor(colors.white)
|
||||
monitor.write("X")
|
||||
monitor.setBackgroundColor(colors.black)
|
||||
|
||||
-- Create window for program
|
||||
local win = window.create(monitor, 1, 2, w, h - 1)
|
||||
local oldTerm = term.redirect(win)
|
||||
|
||||
-- Lifecycle: START
|
||||
if programModule.start then
|
||||
local ok, err = pcall(programModule.start)
|
||||
if not ok then
|
||||
print("Error in start(): " .. tostring(err))
|
||||
term.redirect(oldTerm)
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
-- Lifecycle: MAIN (Run in parallel with exit watcher)
|
||||
local function runMain()
|
||||
-- We wrap main in pcall to catch errors without crashing the driver
|
||||
local ok, err = pcall(programModule.main)
|
||||
if not ok then
|
||||
win.setTextColor(colors.red)
|
||||
win.write("Runtime Error: " .. tostring(err))
|
||||
sleep(2) -- Let user see error
|
||||
end
|
||||
end
|
||||
|
||||
local function watchExit()
|
||||
while true do
|
||||
local _, _, x, y = os.pullEvent("monitor_touch")
|
||||
if x == w and y == 1 then
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
parallel.waitForAny(runMain, watchExit)
|
||||
|
||||
-- Lifecycle: STOP
|
||||
if programModule.stop then
|
||||
pcall(programModule.stop)
|
||||
end
|
||||
|
||||
term.redirect(oldTerm)
|
||||
return true
|
||||
end
|
||||
|
||||
local function exitProgram()
|
||||
isRunning = false
|
||||
end
|
||||
|
||||
local function drawList()
|
||||
monitor.clear()
|
||||
monitor.setCursorPos(1, 1)
|
||||
monitor.write("Available Programs:")
|
||||
|
||||
for i, program in ipairs(programs) do
|
||||
monitor.setCursorPos(1, i + 2) -- Start from line 3
|
||||
monitor.write(i .. ". " .. program.name)
|
||||
end
|
||||
|
||||
monitor.setCursorPos(1, #programs + 4)
|
||||
monitor.write("Click to run")
|
||||
end
|
||||
|
||||
local function listPrograms()
|
||||
isRunning = true
|
||||
while isRunning do
|
||||
drawList()
|
||||
|
||||
local event, side, x, y = os.pullEvent("monitor_touch")
|
||||
local programIndex = y - 2
|
||||
|
||||
if programIndex > 0 and programIndex <= #programs then
|
||||
local program = programs[programIndex]
|
||||
monitor.clear()
|
||||
monitor.setCursorPos(1,1)
|
||||
monitor.write("Running " .. program.name .. "...")
|
||||
sleep(0.5)
|
||||
runProgram(program.program)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return {
|
||||
addProgram = addProgram,
|
||||
runProgram = runProgram,
|
||||
exitProgram = exitProgram,
|
||||
listPrograms = listPrograms
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
local max = 310
|
||||
local min = 300
|
||||
|
||||
|
||||
local function getValue()
|
||||
local kelvin = reactor.getTemperature() or 0
|
||||
local fahrenheit = (kelvin - 273.15) * 9 / 5 + 32
|
||||
return math.floor(fahrenheit * 10000 + 0.5) / 10000
|
||||
end
|
||||
|
||||
local function checkTemperature()
|
||||
local temperature = getValue()
|
||||
local upperThreshold = max - 1
|
||||
local lowerThreshold = min + 1
|
||||
|
||||
if temperature >= upperThreshold then
|
||||
print("Warning: Temperature approaching upper limit! Taking action.")
|
||||
burnRateDriver.stepDown()
|
||||
elseif temperature <= lowerThreshold then
|
||||
print("Warning: Temperature approaching lower limit! Taking action.")
|
||||
burnRateDriver.slowStepUp()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function watch()
|
||||
while true do
|
||||
print("Temperature: " .. getValue())
|
||||
checkTemperature()
|
||||
sleep(0.05) -- Update every tenth second
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function startup()
|
||||
end
|
||||
|
||||
local function shutdown()
|
||||
end
|
||||
|
||||
|
||||
local function report()
|
||||
local value = getValue()
|
||||
local color = colors.black
|
||||
monitor.setBackgroundColor(color)
|
||||
setNewLine()
|
||||
monitor.write("Temperature: " .. value .. "F")
|
||||
end
|
||||
return { report = report, watch = watch, startup = startup, shutdown = shutdown }
|
||||
@@ -1,64 +0,0 @@
|
||||
local max = 99
|
||||
local maxVent = 90
|
||||
local minVent = 95
|
||||
local min = 80
|
||||
|
||||
local function getValue()
|
||||
return turbine.getSteamFilledPercentage() * 100
|
||||
end
|
||||
|
||||
local function color()
|
||||
local value = getValue()
|
||||
return colors.black
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function checkSteamLevel()
|
||||
local value = getValue()
|
||||
if value > max then
|
||||
print("Warning: Steam above maximum! Taking action.")
|
||||
reactor.scram();
|
||||
turbine.setDumpingMode("DUMPING")
|
||||
burnRateDriver.stepDown()
|
||||
elseif value >= maxVent-1 then
|
||||
print("Steam within vent range. Adjusting vents.")
|
||||
turbine.setDumpingMode("DUMPING")
|
||||
burnRateDriver.stepDown()
|
||||
elseif value >= min and value < minVent then
|
||||
print("Steam within normal operation range.")
|
||||
turbine.setDumpingMode("IDLE")
|
||||
--burnRateDriver.stepDown()
|
||||
elseif value < min then
|
||||
print("Warning: Steam below minimum! Taking action.")
|
||||
turbine.setDumpingMode("IDLE")
|
||||
end
|
||||
end
|
||||
|
||||
local function startup()
|
||||
return
|
||||
end
|
||||
|
||||
local function shutdown()
|
||||
end
|
||||
|
||||
local function watch()
|
||||
while true do
|
||||
checkSteamLevel()
|
||||
sleep(0.05) -- Update every tenth second
|
||||
end
|
||||
end
|
||||
|
||||
local function report()
|
||||
local color = color()
|
||||
monitor.setBackgroundColor(color)
|
||||
value = getValue()
|
||||
|
||||
setNewLine()
|
||||
monitor.write("Turbine Steam: " .. value .. "%")
|
||||
|
||||
setNewLine()
|
||||
monitor.write("Turbine Vent: " .. turbine.getDumpingMode())
|
||||
end
|
||||
|
||||
return { report = report, watch = watch, startup = startup, shutdown = shutdown }
|
||||
Reference in New Issue
Block a user