added protected peripheral manager and file system logger

This commit is contained in:
Mikayla Fischler 2022-03-10 14:09:21 -05:00
parent 3c67ee08a8
commit ea84563bb4
2 changed files with 170 additions and 0 deletions

43
scada-common/log.lua Normal file
View File

@ -0,0 +1,43 @@
--
-- File System Logger
--
-- we use extra short abbreviations since computer craft screens are very small
-- underscores are used since some of these names are used elsewhere (e.g. 'debug' is a lua table)
local file_handle = fs.open("/log.txt", "a")
local _log = function (msg)
local stamped = os.date("[%c] ") .. msg
file_handle.writeLine(stamped)
file_handle.flush()
end
function _debug(msg, trace)
local dbg_info = ""
if trace then
local name = ""
if debug.getinfo(2).name ~= nil then
name = ":" .. debug.getinfo(2).name .. "():"
end
dbg_info = debug.getinfo(2).short_src .. ":" .. name ..
debug.getinfo(2).currentline .. " > "
end
_log("[DBG] " .. dbg_info .. msg)
end
function _warning(msg)
_log("[WRN] " .. msg)
end
function _error(msg)
_log("[ERR] " .. msg)
end
function _fatal(msg)
_log("[FTL] " .. msg)
end

127
scada-common/ppm.lua Normal file
View File

@ -0,0 +1,127 @@
-- #REQUIRES log.lua
--
-- Protected Peripheral Manager
--
function ppm()
local self = {
mounts = {}
}
-- wrap peripheral calls with lua protected call
-- ex. reason: we don't want a disconnect to crash the program before a SCRAM
local peri_init = function (device)
for key, func in pairs(device) do
device[key] = function (...)
local status, result = pcall(func, ...)
if status then
return result
else
-- function failed
log._error("protected " .. key .. "() -> " .. result)
return nil
end
end
end
end
-- mount all available peripherals (clears mounts first)
local mount_all = function ()
local ifaces = peripheral.getNames()
self.mounts = {}
for i = 1, #ifaces do
local pm_dev = peripheral.wrap(ifaces[i])
peri_init(pm_dev)
self.mounts[ifaces[i]] = { peripheral.getType(ifaces[i]), pm_dev }
end
end
-- mount a particular device
local mount = function (name)
local ifaces = peripheral.getNames()
local pm_dev = nil
for i = 1, #ifaces do
if name == peripheral.getType(ifaces[i]) then
pm_dev = peripheral.wrap(ifaces[i])
peri_init(pm_dev)
self.mounts[ifaces[i]] = {
type = peripheral.getType(ifaces[i]),
device = pm_dev
}
break
end
end
return pm_dev
end
-- handle peripheral_detach event
local unmount_handler = function (iface)
-- what got disconnected?
local lost_dev = self.mounts[iface]
local type = lost_dev.type
log._warning("PMGR: lost device " .. type .. " mounted to " .. iface)
return self.mounts[iface]
end
-- list all available peripherals
local list_avail = function ()
return peripheral.getNames()
end
-- list mounted peripherals
local list_mounts = function ()
return self.mounts
end
-- get a mounted peripheral by side/interface
local get_periph = function (iface)
return self.mounts[iface].device
end
-- get a mounted peripheral by type
local get_device = function (name)
local device = nil
for side, data in pairs(self.mounts) do
if data.type == name then
device = data.device
break
end
end
return device
end
-- list all connected monitors
local list_monitors = function ()
local monitors = {}
for side, data in pairs(self.mounts) do
if data.type == "monitor" then
monitors[side] = data.device
end
end
return monitors
end
return {
mount_all = mount_all,
mount = mount,
umount = unmount_handler,
list_avail = list_avail,
list_mounts = list_mounts,
get_periph = get_periph,
get_device = get_device,
list_monitors = list_monitors
}
end