Files

212 lines
7.3 KiB
Lua
Raw Permalink Normal View History

-- install.lua -- ETT entry-point for hele autopiloten. Samme kommando paa begge PC-er:
--
-- wget run https://gt.zyon.no/Stian/airship-autopilot/raw/branch/main/install.lua
--
-- Installeren DETEKTERER selv hvilken PC den staar paa (flysensorer = autopilot,
-- monitor = cockpit), installerer riktig rolle, og gaar RETT videre i setup/oppstart --
-- ingen reboot, ingen rollenavn aa huske. Re-run samme kommando for aa oppdatere.
-- Eksplisitt rolle som argument overstyrer deteksjonen (avansert):
-- wget run .../install.lua autopilot | cockpit
--
-- Roles:
-- autopilot machine-room PC: full v3 observer autopilot (setup wizard / standby)
-- cockpit pilot-house PC: control console (monitor + modem)
--
-- Per-skip TILSTAND (sides/calib/target/settings) shippes ALDRI av installeren -- den maales
-- av setup-wizarden PAA skipet. Ved re-install kan profilen beholdes eller nullstilles.
-- Filer som er fjernet fra manifestet siden sist (eller kjente legacy-filer) ryddes bort.
local BASE = "https://gt.zyon.no/Stian/airship-autopilot/raw/branch/main"
local ROLES = { "autopilot", "cockpit" }
-- per-skip tilstand: roeres aldri automatisk, men tilbys nullstilt ved install
local STATE_FILES = { "sides.txt", "calib.txt", "target.txt", "settings.txt", "engaged.txt" }
-- kjente filer fra eldre versjoner som ikke lenger hoerer til rollen (engangs-rydding;
-- videre oppdateringer ryddes automatisk via installasjons-loggen .installed_<role>)
local LEGACY = {
autopilot = { "stabilize.lua", "diag.lua", "probe.lua", "scan.lua", "scan.txt",
"pid_gains.txt", "cockpit.lua", "pilot_startup.lua" },
cockpit = {},
}
local args = { ... }
-- ---- helpers ---------------------------------------------------------------
local function die(msg)
term.setTextColor(colors.red)
print(msg)
term.setTextColor(colors.white)
error("", 0)
end
local function get(url)
local h, err = http.get(url)
if not h then return nil, tostring(err) end
local body = h.readAll()
h.close()
return body
end
local function writeFile(path, data)
local dir = fs.getDir(path)
if dir ~= "" and not fs.exists(dir) then fs.makeDir(dir) end
local f = fs.open(path, "w")
f.write(data)
f.close()
end
local function inList(list, x)
for _, v in ipairs(list) do if v == x then return true end end
return false
end
local function chooseRole()
print("Select role to install:")
print(" 1) autopilot (machine room -- has the")
print(" altitude + gimbal sensors)")
print(" 2) cockpit (pilot house -- has a")
print(" monitor + modem)")
write("> ")
local sel = read()
local n = tonumber(sel)
if n and ROLES[n] then return ROLES[n] end
for _, r in ipairs(ROLES) do if r == sel then return r end end
die("Unknown role: " .. tostring(sel))
end
-- gjett rollen ut fra hva som er koblet til: flysensorer er det sterkeste signalet
-- (maskinrommet kan ogsaa ha monitor), deretter monitor -> cockpit
local function detectRole()
if peripheral.find("altitude_sensor") or peripheral.find("gimbal_sensor") then
return "autopilot", "flight sensors attached"
end
if peripheral.find("monitor") then
return "cockpit", "monitor attached, no flight sensors"
end
return nil
end
-- ---- preflight -------------------------------------------------------------
if not http then
die("HTTP API is disabled on this server.\n" ..
"Enable it in the server's computercraft-server.toml:\n" ..
" [http] enabled = true then restart the server.")
end
local role = args[1]
if role then
local ok = false
for _, r in ipairs(ROLES) do if r == role then ok = true end end
if not ok then die("Unknown role '" .. role .. "'. Valid: " .. table.concat(ROLES, ", ")) end
else
local guess, why = detectRole()
if guess then
print("This looks like the " ..
(guess == "autopilot" and "MACHINE-ROOM" or "PILOT-HOUSE") .. " PC")
print(" (" .. why .. ")")
write("Install '" .. guess .. "'? [Y/n] ")
role = (read():lower() == "n") and chooseRole() or guess
else
print("Could not auto-detect this PC's role")
print("(no flight sensors or monitor attached).")
role = chooseRole()
end
end
-- ---- fetch manifest --------------------------------------------------------
print("Installing role: " .. role)
local manifestUrl = BASE .. "/files/" .. role .. "/manifest"
local manifest, mErr = get(manifestUrl)
if not manifest then die("Could not fetch manifest (" .. mErr .. ")\n" .. manifestUrl) end
local files = {}
for line in manifest:gmatch("[^\r\n]+") do
local p = line:match("^%s*(.-)%s*$")
if p ~= "" then files[#files + 1] = p end
end
if #files == 0 then die("Manifest is empty: " .. manifestUrl) end
-- ---- download --------------------------------------------------------------
local ok, fail = 0, {}
for i, rel in ipairs(files) do
term.write(("[%d/%d] %s "):format(i, #files, rel))
local data, err = get(BASE .. "/files/" .. role .. "/" .. rel)
if data then
writeFile(rel, data)
term.setTextColor(colors.green); print("ok"); term.setTextColor(colors.white)
ok = ok + 1
else
term.setTextColor(colors.red); print("FAIL"); term.setTextColor(colors.white)
fail[#fail + 1] = rel .. " (" .. tostring(err) .. ")"
end
end
print(("Installed %d/%d files."):format(ok, #files))
if #fail > 0 then
term.setTextColor(colors.red)
print("Failed:")
for _, f in ipairs(fail) do print(" " .. f) end
term.setTextColor(colors.white)
die("Install incomplete -- re-run after fixing the errors above.")
end
-- ---- rydd: legacy + filer fjernet fra manifestet siden forrige install ------
local removed = 0
for _, f in ipairs(LEGACY[role] or {}) do
if fs.exists(f) then fs.delete(f); removed = removed + 1; print("removed legacy: " .. f) end
end
local RECORD = ".installed_" .. role
if fs.exists(RECORD) then
local rf = fs.open(RECORD, "r"); local prev = rf.readAll(); rf.close()
for line in (prev or ""):gmatch("[^\r\n]+") do
local p = line:match("^%s*(.-)%s*$")
if p ~= "" and not inList(files, p) and not inList(STATE_FILES, p) and fs.exists(p) then
fs.delete(p); removed = removed + 1; print("removed obsolete: " .. p)
end
end
end
writeFile(RECORD, table.concat(files, "\n") .. "\n")
if removed > 0 then print(("Cleaned up %d old file(s)."):format(removed)) end
-- ---- skip-profil: behold eller nullstill (ETTER vellykket install, foer boot) ----
-- (kun autopilot-rollen har skip-tilstand; sletter aldri noe hvis nedlastingen feilet)
if role == "autopilot" then
local found = {}
for _, f in ipairs(STATE_FILES) do if fs.exists(f) then found[#found + 1] = f end end
if #found > 0 then
print("Existing ship profile found:")
print(" " .. table.concat(found, ", "))
write("Keep it? (n = new/rewired ship) [Y/n] ")
if read():lower() == "n" then
for _, f in ipairs(found) do fs.delete(f) end
print("Profile reset -- the setup wizard takes over.")
end
end
end
-- ---- ferdig: gaa RETT videre (ingen reboot noedvendig) ----------------------
-- startup.lua er installert, saa alt auto-starter ved fremtidige reboots; naa
-- fortsetter vi direkte inn i samme flyt som boot ville gitt.
term.setTextColor(colors.green)
print("Done. (auto-starts on every reboot)")
term.setTextColor(colors.white)
print("")
if role == "autopilot" then
print("Continuing into setup/standby...")
sleep(1.0)
shell.run("ap", "boot")
else
print("Starting the pilot console...")
sleep(1.0)
shell.run("cockpit")
end