CODE
----------------------------------------------------------------------------------------------------------
-- Name: OutOfPaperErrors.lua
-- Author: Robert Aronsson, Intellipool AB
-- Version: 1.0
-- Date: 2009-05-15
--
-- Prerequisite: Works only with Windows printers.
-- Script published "AS IS", no warranties made.
--
-- Description:
--
-- The script checks the number of out of paper errors logged by the monitored printer.
-- The first test done is a base line used to compare coming tests with. The counter that is queried is
-- an ever increasing value that accumulates the number of out of paper errors between restarts of the
-- printer server. Due to this, another counter is sampled as well, the pending Jobs counter. Using
-- the number of current jobs we can track if the printer now have paper and have started to print again.
--
-- Note that this is in no way a fool proof way to detect out of paper conditions, and its pretty expensive test.
--
-- Keep the test time to at least 2 minutes, observe the functionality and make necessary adjustmetns if
-- you detect a condition where it do not behave as intended.
--
--
-- Arguments: Name of printer
----------------------------------------------------------------------------------------------------------
function OnEnumerate(sFieldToEnum)
       Enum = LuaScriptEnumResult()
       return Enum
end

function OnConfigure()

    Config = LuaScriptConfigurator()

    -- Author.
    Config:SetAuthor("Robert Aronsson, Intellipool AB")

    -- Description.
    Config:SetDescription("Detects out of paper conditions on Windows printers. For detailed specification of monitor, read script header.")

    -- Minimum build version of INM, set to zero for if no specific build version is required.
    Config:SetMinBuildVersion(4641)

    -- Script version (major/minor)
    Config:SetScriptVersion(1,0)

    Config:AddArgument( "Printer name", "Name of printer to check" ,LuaScriptConfigurator.CHECK_NOT_EMPTY)
      Config:SetEntryPoint("main")
      return Config
end


---------------------------------------------------------

function main()

    Storage = TLuaStorage()

    -- Get the name of the printer
    PrinterName = GetArgument(0)

    -- some variables
    iNumberOfPreviousJobs = 0
    iNumberOfCurrentJobs = 0
    iOutOfPaperValue = 0.0;
    iNewOutOfPaperValue = 0.0;

    -- First test just samples the out of papper value
    bFirstTest = false
    
    -- Create a new storage item if needed
    if(Storage:CreateItem("PM_OutOfPaper","value")==false) then
        StorageItem = Storage:FindItem("PM_OutOfPaper","value")
        if(StorageItem.m_pData ~= nil) then
            iOutOfPaperValue = tonumber(StorageItem.m_pData)
        end
    else
        -- No item found, this is the first test since creation of monitor or restart of INM
        bFirstTest = true    
    end

    -- Create a new storage item if needed
    if(Storage:CreateItem("PM_Jobs","value")==false) then
        StorageItem = Storage:FindItem("PM_Jobs","value")
        if(StorageItem.m_pData ~= nil) then
            iNumberOfPreviousJobs = tonumber(StorageItem.m_pData)
        end
    end
        
    Winperf = TLuaWinperf()
    if(Winperf:Query("Print Queue","Out of Paper Errors",PrinterName) == true) then
        -- Get the printer out of paper value
        iNewOutOfPaperValue = Winperf:GetResult()

        -- Get the number of jobs on printer
        if(Winperf:Query("Print Queue","Jobs",PrinterName) == true) then
            iNumberOfCurrentJobs = Winperf:GetResult()
        else
            -- We are assuming that this will never happen;)
        end

        -- Store current number of jobs for next test
        sTemp = tostring(iNumberOfCurrentJobs)
        Storage:UpdateItem("PM_Jobs","value",sTemp)

        -- Check if its the first query, then just store the value
        if(bFirstTest == false) then
            -- Some debug info
            -- print("Previous out of paper"..iOutOfPaperValue)
            -- print("New Out of paper"..iNewOutOfPaperValue)
            -- print("Current jobs"..iNumberOfCurrentJobs)
            -- print("Previous jobs"..iNumberOfPreviousJobs)
        
            -- If out of paper errors have increesed, alarm!
            if(iNewOutOfPaperValue > iOutOfPaperValue) then
                -- Still larger than previous stored value, check number of jobs
                SetExitStatus("Printer "..PrinterName.." reporting out of paper",false)
                if(iNumberOfCurrentJobs < iNumberOfPreviousJobs) then
                    -- The number of jobs have decreesed, which we take as a sign that the printer now have paper
                    -- So we store the new out of paper value
                    sTemp = tostring(iNewOutOfPaperValue)
                    Storage:UpdateItem("PM_OutOfPaper","value",sTemp)
                    SetExitStatus("Printer "..PrinterName.." ok",true)
                end
                return
            end
        else
            -- store it of next test
            sTemp = tostring(iNewOutOfPaperValue)
            Storage:UpdateItem("PM_OutOfPaper","value",sTemp)
        end
        -- this will also be called if the printer server have restarted, since the new printer out of papper value will be less than the old one
        SetExitStatus("Printer "..PrinterName.." ok",true)            
    else
        SetExitStatus("Could not query out of papper errors from printer "..PrinterName,false)
        return
    end
end