Stabilize boiler mapping and clutch fail-safe
This commit is contained in:
@@ -39,13 +39,15 @@ eine Campfire- oder Blaze-Burner-Waermequelle erkannt wird.
|
|||||||
|
|
||||||
### Clutch-Teststeuerung
|
### Clutch-Teststeuerung
|
||||||
|
|
||||||
Die rechte Seite des Computers ist als direkter Redstone-Ausgang fuer eine Test-Clutch
|
Die linke Seite des Computers ist als Redstone-Ausgang fuer die Test-Clutch konfiguriert.
|
||||||
konfiguriert. Der Touch-Button auf dem Advanced Monitor schaltet diesen Ausgang ohne
|
Zwischen Ausgang und Clutch sitzt eine Redstone-Fackel als Fail-safe-Inverter: Ausgang `ON`
|
||||||
Invertierung zwischen `CLUTCH SIGNAL: OFF` und `CLUTCH SIGNAL: ON` um. Die Verbindung kann
|
bedeutet `PRODUCTION: RUNNING`; Ausgang `OFF`, Programmabbruch oder Computerneustart bedeutet
|
||||||
direkt mit Redstone oder drahtlos ueber ein abgestimmtes Paar Create Redstone Links erfolgen.
|
`PRODUCTION: STOPPED`. Die Verbindung kann direkt oder ueber Create Redstone Links erfolgen.
|
||||||
Die Boiler-Zuordnung erfolgt nach den internen Peripheral-Namen; die drei Block Reader sollten
|
|
||||||
deshalb in der Reihenfolge Boiler 1 bis 3 an das Wired Network angeschlossen werden. Jeder Block
|
Die Boiler werden nicht anhand wechselnder Peripheral-Namen, sondern fest ueber ihre
|
||||||
Reader muss auf den Controller-Tank des zugeordneten Boiler-Multiblocks zeigen.
|
Controller-Koordinaten `11266/64/10810`, `11260/64/10810` und `11252/64/10810` zugeordnet.
|
||||||
|
Fehlt ein Reader, bleibt dadurch exakt die betroffene Boiler-Zeile auf `MISSING / NO READER`.
|
||||||
|
Jeder Block Reader muss direkt auf den Controller-Tank seines Boiler-Multiblocks zeigen.
|
||||||
|
|
||||||
## Struktur
|
## Struktur
|
||||||
|
|
||||||
|
|||||||
+41
-16
@@ -1,11 +1,16 @@
|
|||||||
-- Create boiler status board for CC:Tweaked.
|
-- Create boiler status board for CC:Tweaked.
|
||||||
-- All Create values are read through Advanced Peripherals Block Readers.
|
-- All Create values are read through Advanced Peripherals Block Readers.
|
||||||
|
|
||||||
local EXPECTED_BOILERS = 3
|
|
||||||
local REFRESH_SECONDS = 1
|
local REFRESH_SECONDS = 1
|
||||||
local MIN_WIDTH = 38
|
local MIN_WIDTH = 38
|
||||||
local MIN_HEIGHT = 14
|
local MIN_HEIGHT = 14
|
||||||
local CLUTCH_OUTPUT_SIDE = "right"
|
local CLUTCH_OUTPUT_SIDE = "left"
|
||||||
|
|
||||||
|
local BOILERS = {
|
||||||
|
{ label = "BOILER 1", position = { 11266, 64, 10810 } },
|
||||||
|
{ label = "BOILER 2", position = { 11260, 64, 10810 } },
|
||||||
|
{ label = "BOILER 3", position = { 11252, 64, 10810 } },
|
||||||
|
}
|
||||||
|
|
||||||
local clutchButton = { x1 = 0, x2 = 0, y = 0 }
|
local clutchButton = { x1 = 0, x2 = 0, y = 0 }
|
||||||
|
|
||||||
@@ -64,6 +69,13 @@ local function samePosition(a, b)
|
|||||||
and tonumber(a[3]) == tonumber(b[3])
|
and tonumber(a[3]) == tonumber(b[3])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function positionKey(position)
|
||||||
|
if type(position) ~= "table" then return nil end
|
||||||
|
local x, y, z = tonumber(position[1]), tonumber(position[2]), tonumber(position[3])
|
||||||
|
if not x or not y or not z then return nil end
|
||||||
|
return ("%d,%d,%d"):format(x, y, z)
|
||||||
|
end
|
||||||
|
|
||||||
local function discoverReaders()
|
local function discoverReaders()
|
||||||
local boilers, networks = {}, {}
|
local boilers, networks = {}, {}
|
||||||
local names = peripheral.getNames()
|
local names = peripheral.getNames()
|
||||||
@@ -78,7 +90,9 @@ local function discoverReaders()
|
|||||||
local speed = getValueIgnoringCase(data, { "Speed" })
|
local speed = getValueIgnoringCase(data, { "Speed" })
|
||||||
|
|
||||||
if type(boiler) == "table" then
|
if type(boiler) == "table" then
|
||||||
boilers[#boilers + 1] = { name = name, data = data, boiler = boiler }
|
local position = getValueIgnoringCase(data, { "LastKnownPos", "Controller" })
|
||||||
|
local key = positionKey(position)
|
||||||
|
if key then boilers[key] = { name = name, data = data, boiler = boiler } end
|
||||||
elseif type(network) == "table" and tonumber(speed) then
|
elseif type(network) == "table" and tonumber(speed) then
|
||||||
networks[#networks + 1] = { name = name, data = data, network = network }
|
networks[#networks + 1] = { name = name, data = data, network = network }
|
||||||
end
|
end
|
||||||
@@ -136,8 +150,10 @@ end
|
|||||||
|
|
||||||
local function drawClutchButton(height)
|
local function drawClutchButton(height)
|
||||||
local width = monitor.getSize()
|
local width = monitor.getSize()
|
||||||
local signal = redstone.getOutput(CLUTCH_OUTPUT_SIDE)
|
-- With the external redstone-torch inverter, output ON means the clutch is
|
||||||
local label = signal and " CLUTCH SIGNAL: ON " or " CLUTCH SIGNAL: OFF "
|
-- unpowered and production runs. Output OFF is the fail-safe stopped state.
|
||||||
|
local running = redstone.getOutput(CLUTCH_OUTPUT_SIDE)
|
||||||
|
local label = running and " PRODUCTION: RUNNING " or " PRODUCTION: STOPPED "
|
||||||
local x = math.max(1, math.floor((width - #label) / 2) + 1)
|
local x = math.max(1, math.floor((width - #label) / 2) + 1)
|
||||||
local y = math.max(13, height - 1)
|
local y = math.max(13, height - 1)
|
||||||
|
|
||||||
@@ -149,15 +165,15 @@ local function drawClutchButton(height)
|
|||||||
monitor.setBackgroundColor(colors.black)
|
monitor.setBackgroundColor(colors.black)
|
||||||
monitor.write((" "):rep(width))
|
monitor.write((" "):rep(width))
|
||||||
monitor.setCursorPos(x, y)
|
monitor.setCursorPos(x, y)
|
||||||
monitor.setBackgroundColor(signal and colors.orange or colors.gray)
|
monitor.setBackgroundColor(running and colors.lime or colors.red)
|
||||||
monitor.setTextColor(colors.black)
|
monitor.setTextColor(colors.black)
|
||||||
monitor.write(label)
|
monitor.write(label)
|
||||||
monitor.setBackgroundColor(colors.black)
|
monitor.setBackgroundColor(colors.black)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function toggleClutchSignal()
|
local function toggleProduction()
|
||||||
local signal = redstone.getOutput(CLUTCH_OUTPUT_SIDE)
|
local running = redstone.getOutput(CLUTCH_OUTPUT_SIDE)
|
||||||
redstone.setOutput(CLUTCH_OUTPUT_SIDE, not signal)
|
redstone.setOutput(CLUTCH_OUTPUT_SIDE, not running)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function render()
|
local function render()
|
||||||
@@ -169,9 +185,10 @@ local function render()
|
|||||||
monitor.clear()
|
monitor.clear()
|
||||||
center(1, "CREATE KRAFTWERK", colors.cyan)
|
center(1, "CREATE KRAFTWERK", colors.cyan)
|
||||||
|
|
||||||
for index = 1, EXPECTED_BOILERS do
|
for index, configuredBoiler in ipairs(BOILERS) do
|
||||||
local state, heatMode, color = readBoiler(boilers[index])
|
local reader = boilers[positionKey(configuredBoiler.position)]
|
||||||
center(2 + index, ("BOILER %d %-7s %s"):format(index, state, heatMode), color)
|
local state, heatMode, color = readBoiler(reader)
|
||||||
|
center(2 + index, ("%s %-7s %s"):format(configuredBoiler.label, state, heatMode), color)
|
||||||
end
|
end
|
||||||
|
|
||||||
center(7, "MAIN SHAFT", colors.cyan)
|
center(7, "MAIN SHAFT", colors.cyan)
|
||||||
@@ -187,7 +204,7 @@ local function render()
|
|||||||
end
|
end
|
||||||
|
|
||||||
drawClutchButton(height)
|
drawClutchButton(height)
|
||||||
center(height, "Touch = Redstone umschalten", colors.gray)
|
center(height, "Touch = Produktion umschalten", colors.gray)
|
||||||
monitor.setTextColor(colors.white)
|
monitor.setTextColor(colors.white)
|
||||||
monitor.setBackgroundColor(colors.black)
|
monitor.setBackgroundColor(colors.black)
|
||||||
term.setCursorPos(1, 1)
|
term.setCursorPos(1, 1)
|
||||||
@@ -206,16 +223,24 @@ end
|
|||||||
safeRender()
|
safeRender()
|
||||||
local refreshTimer = os.startTimer(REFRESH_SECONDS)
|
local refreshTimer = os.startTimer(REFRESH_SECONDS)
|
||||||
|
|
||||||
|
local function run()
|
||||||
while true do
|
while true do
|
||||||
local event, first, second, third = os.pullEvent()
|
local event, first, second, third = os.pullEventRaw()
|
||||||
if event == "timer" and first == refreshTimer then
|
if event == "terminate" then
|
||||||
|
return
|
||||||
|
elseif event == "timer" and first == refreshTimer then
|
||||||
safeRender()
|
safeRender()
|
||||||
refreshTimer = os.startTimer(REFRESH_SECONDS)
|
refreshTimer = os.startTimer(REFRESH_SECONDS)
|
||||||
elseif event == "monitor_touch" then
|
elseif event == "monitor_touch" then
|
||||||
local x, y = second, third
|
local x, y = second, third
|
||||||
if y == clutchButton.y and x >= clutchButton.x1 and x <= clutchButton.x2 then
|
if y == clutchButton.y and x >= clutchButton.x1 and x <= clutchButton.x2 then
|
||||||
toggleClutchSignal()
|
toggleProduction()
|
||||||
safeRender()
|
safeRender()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local ok, reason = pcall(run)
|
||||||
|
redstone.setOutput(CLUTCH_OUTPUT_SIDE, false)
|
||||||
|
if not ok then error(reason, 0) end
|
||||||
|
|||||||
Reference in New Issue
Block a user