summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--controller.lua11
-rw-r--r--controllerfw.lua29
-rw-r--r--drive_entity.lua23
-rw-r--r--drive_null.lua5
4 files changed, 58 insertions, 10 deletions
diff --git a/controller.lua b/controller.lua
index 3de026c..8d6b210 100644
--- a/controller.lua
+++ b/controller.lua
@@ -400,7 +400,7 @@ function celevator.controller.finddrive(pos)
return drivepos,minetest.registered_nodes[drivename]._celevator_drive_type
end
-function celevator.controller.finish(pos,mem)
+function celevator.controller.finish(pos,mem,changedinterrupts)
if not celevator.controller.iscontroller(pos) then
return
else
@@ -416,9 +416,11 @@ function celevator.controller.finish(pos,mem)
elseif command.command == "estop" then
celevator.drives[drivetype].estop(drivepos)
elseif command.command == "open" then
- celevator.drives[drivetype].movedoors(drivepos,"open")
+ minetest.after(0.25,celevator.drives[drivetype].movedoors,drivepos,"open")
elseif command.command == "close" then
celevator.drives[drivetype].movedoors(drivepos,"close")
+ elseif command.command == "resetfault" then
+ celevator.drives[drivetype].resetfault(drivepos)
end
end
end
@@ -479,7 +481,10 @@ function celevator.controller.finish(pos,mem)
meta:set_string("formspec_hidden",mem.formspec or "")
meta:set_string("infotext",mem.infotext or "")
local hash = minetest.hash_node_position(pos)
- celevator.controller.iqueue[hash] = mem.interrupts
+ if not celevator.controller.iqueue[hash] then celevator.controller.iqueue[hash] = mem.interrupts end
+ for iid in pairs(changedinterrupts) do
+ celevator.controller.iqueue[hash][iid] = mem.interrupts[iid]
+ end
celevator.storage:set_string("controller_iqueue",minetest.serialize(celevator.controller.iqueue))
controllerleds(pos,mem.showrunning)
celevator.controller.running[hash] = nil
diff --git a/controllerfw.lua b/controllerfw.lua
index 9491396..abfc358 100644
--- a/controllerfw.lua
+++ b/controllerfw.lua
@@ -1,5 +1,7 @@
local pos,event,mem = ...
+local changedinterrupts = {}
+
local function fault(ftype,fatal)
if fatal then mem.fatalfault = true end
if not mem.activefaults then mem.activefaults = {} end
@@ -17,6 +19,8 @@ if not mem.drive.status then
vel = 0,
maxvel = 0,
}
+elseif mem.drive.status.fault then
+ fault("drive"..mem.drive.status.fault,true)
end
if mem.drive.state == "uninit" then
@@ -51,8 +55,13 @@ local doorstates = {
}
local faultnames = {
+ opentimeout = "Door Open Timeout",
+ closetimeout = "Door Close Timeout",
drivecomm = "Lost Communication With Drive",
driveuninit = "Drive Not Configured",
+ drivemetaload = "Drive Metadata Load Failure",
+ drivebadorigin = "Drive Origin Invalid",
+ drivedoorinterlock = "Attempted to Move Doors With Car in Motion",
}
local function drivecmd(command)
@@ -61,13 +70,16 @@ end
local function interrupt(time,iid)
mem.interrupts[iid] = time
+ changedinterrupts[iid] = true
end
-local function getpos()
+local function getpos(pioffset)
local ret = 0
+ local searchpos = mem.drive.status.apos
+ if pioffset then searchpos = math.max(0,searchpos+0.5) end
for k,v in ipairs(mem.params.floorheights) do
ret = ret+v
- if ret > mem.drive.status.apos then return k end
+ if ret > searchpos then return k end
end
return mem.params.floorheights[#mem.params.floorheights]
end
@@ -163,12 +175,14 @@ local function open()
mem.doorstate = "opening"
drivecmd({command = "open"})
interrupt(0.2,"checkopen")
+ interrupt(10,"opentimeout")
end
local function close()
mem.doorstate = "closing"
drivecmd({command = "close"})
interrupt(0.2,"checkclosed")
+ interrupt(10,"closetimeout")
end
mem.formspec = ""
@@ -374,6 +388,7 @@ elseif event.type == "ui" then
mem.faultlog = {}
mem.activefaults = {}
mem.fatalfault = false
+ drivecmd({command = "resetfault"})
end
end
elseif event.iid == "opened" and mem.doorstate == "opening" then
@@ -409,15 +424,21 @@ elseif event.type == "callbutton" and mem.carstate == "normal" then
elseif event.iid == "checkopen" then
if mem.drive.status.doorstate == "open" then
interrupt(0,"opened")
+ interrupt(nil,"opentimeout")
else
interrupt(0.2,"checkopen")
end
elseif event.iid == "checkclosed" then
if mem.drive.status.doorstate == "closed" then
interrupt(0,"closed")
+ interrupt(nil,"closetimeout")
else
interrupt(0.2,"checkclosed")
end
+elseif event.iid == "opentimeout" then
+ fault("opentimeout",true)
+elseif event.iid == "closetimeout" then
+ fault("closetimeout",true)
end
local oldstate = mem.carstate
@@ -727,7 +748,7 @@ else
mem.showrunning = false
end
-mem.pifloor = mem.params.floornames[getpos()]
+mem.pifloor = mem.params.floornames[getpos(true)]
local hidepi = {
bfdemand = true,
uninit = true,
@@ -754,4 +775,4 @@ if mem.carstate == "normal" and (mem.doorstate == "open" or mem.doorstate == "op
mem.lanterns[getpos()] = mem.direction
end
-return pos,mem
+return pos,mem,changedinterrupts
diff --git a/drive_entity.lua b/drive_entity.lua
index 6f4f988..74e58c8 100644
--- a/drive_entity.lua
+++ b/drive_entity.lua
@@ -208,7 +208,9 @@ function celevator.drives.entity.step(dtime)
local origin = minetest.string_to_pos(meta:get_string("origin"))
if not origin then
minetest.log("error","[celevator] [entity drive] Invalid origin for drive at "..minetest.pos_to_string(pos))
+ meta:set_string("fault","badorigin")
table.remove(entitydrives_running,i)
+ return
end
if state == "start" then
sound = true
@@ -370,7 +372,7 @@ function celevator.drives.entity.getstatus(pos,call2)
return celevator.drives.null.get_status(pos,true)
elseif node.name ~= "celevator:drive" then
minetest.log("error","[celevator] [entity drive] Could not load drive status at "..minetest.pos_to_string(pos))
- return
+ return {fault = "metaload"}
else
local meta = minetest.get_meta(pos)
local ret = {}
@@ -380,6 +382,8 @@ function celevator.drives.entity.getstatus(pos,call2)
ret.maxvel = tonumber(meta:get_string("maxvel")) or 0.2
ret.state = meta:get_string("state")
ret.doorstate = meta:get_string("doorstate")
+ ret.fault = meta:get_string("fault")
+ if ret.fault == "" then ret.fault = nil end
return ret
end
end
@@ -387,11 +391,20 @@ end
function celevator.drives.entity.movedoors(drivepos,direction)
local drivehash = minetest.hash_node_position(drivepos)
local entitydrives_running = minetest.deserialize(celevator.storage:get_string("entitydrives_running")) or {}
+ local drivemeta = minetest.get_meta(drivepos)
for _,hash in pairs(entitydrives_running) do
- if drivehash == hash then return end
+ if drivehash == hash then
+ minetest.log("error","[celevator] [entity drive] Attempted to open doors while drive at "..minetest.pos_to_string(drivepos).." was still moving")
+ drivemeta:set_string("fault","doorinterlock")
+ return
+ end
end
- local drivemeta = minetest.get_meta(drivepos)
local origin = minetest.string_to_pos(drivemeta:get_string("origin"))
+ if not origin then
+ minetest.log("error","[celevator] [entity drive] Invalid origin for drive at "..minetest.pos_to_string(drivepos))
+ drivemeta:set_string("fault","badorigin")
+ return
+ end
local apos = tonumber(drivemeta:get_string("apos")) or 0
local carpos = vector.add(origin,vector.new(0,apos,0))
local carnode = minetest.get_node(carpos)
@@ -411,6 +424,10 @@ function celevator.drives.entity.movedoors(drivepos,direction)
end
end
+function celevator.drives.entity.resetfault(pos)
+ minetest.get_meta(pos):set_string("fault","")
+end
+
local function carsearch(pos)
for i=1,500,1 do
local searchpos = vector.subtract(pos,vector.new(0,i,0))
diff --git a/drive_null.lua b/drive_null.lua
index 28c7e04..417d857 100644
--- a/drive_null.lua
+++ b/drive_null.lua
@@ -225,3 +225,8 @@ function celevator.drives.null.getstatus(pos,call2)
return ret
end
end
+
+function celevator.drives.null.resetfault(pos)
+ --This drive has no possible faults at this time (drive communication faults are generated by the controller), but the controller expects to be able to call this
+ minetest.get_meta(pos):set_string("fault","")
+end