diff --git a/src/rest/api/api_printer.lua b/src/rest/api/api_printer.lua index 0b998d1..f510ab0 100644 --- a/src/rest/api/api_printer.lua +++ b/src/rest/api/api_printer.lua @@ -2,6 +2,7 @@ local lfs = require('lfs') local log = require('util.logger') local utils = require('util.utils') local settings = require('util.settings') +local printDriver = require('print3d') local M = { isApi = true @@ -14,21 +15,29 @@ local PROGRESS_FILE = 'progress2.out' local COMMAND_FILE = 'command.in' local GCODE_TMP_FILE = 'combined.gc' --- returns full path + ultifi path or nil -local function printerExists(id) - if id == nil then return nil end - - local path = '/dev/ttyACM' .. id - local upath = ULTIFI_BASE_PATH .. '/ttyACM' .. id - if utils.exists(path) then return path,upath end - - path = '/dev/ttyUSB' .. id - upath = ULTIFI_BASE_PATH .. '/ttyUSB' .. id - if utils.exists(path) then return path,upath end - - return nil + + +--NEW +--returns a printer instance or nil (and sets error state on response in the latter case) +local function createPrinterOrFail(deviceId, response) + local msg,printer = nil, nil + + if deviceId and deviceId ~= "" then + printer,msg = printDriver.getPrinter(deviceId) + else + msg = "missing device ID" + end + + if not printer then + response:setError("could not open printer driver (" .. msg .. ")") + response:addData('id', deviceId) + return nil + end + + return printer end + -- returns printerId,devicePath,ultifiPath or nil if printer does not exist -- when nil is returned, response has already been set as an error local function getPrinterDataOrFail(request, response) @@ -38,47 +47,64 @@ local function getPrinterDataOrFail(request, response) response:setError("missing id argument") return nil end - + local devpath,ultipath = printerExists(id) - + if not devpath then response:setError("printer does not exist") response:addData('id', id) return nil end - + return id,devpath,ultipath end + + +-- returns full path + ultifi path or nil +local function printerExists(id) + if id == nil then return nil end + + local path = '/dev/ttyACM' .. id + local upath = ULTIFI_BASE_PATH .. '/ttyACM' .. id + if utils.exists(path) then return path,upath end + + path = '/dev/ttyUSB' .. id + upath = ULTIFI_BASE_PATH .. '/ttyUSB' .. id + if utils.exists(path) then return path,upath end + + return nil +end + -- assumes printerPath exists, returns true if successful, false if command file already exists and is non-empty (i.e. printer busy), -- nil+err if file could not be opened local function sendGcode(printerPath, gcode) local cmdPath = printerPath .. '/' .. COMMAND_FILE local f,msg = io.open(cmdPath, 'a+') -- 'a+' is important, do not overwrite current contents in any case - + if not f then return nil,msg end if utils.fileSize(f) > 0 then return false end - + log:debug("sending " .. gcode:len() .. " bytes of gcode") f:write(gcode) f:close() - + return true end local function addToGcodeFile(printerPath, gcode) if not gcode or type(gcode) ~= 'string' then return nil,"missing gcode data" end - + local gtFile = printerPath .. '/' .. GCODE_TMP_FILE - + local gcf,msg = io.open(gtFile, 'a+') if not gcf then return nil,msg end - + log:debug("appending " .. gcode:len() .. " bytes of gcode to " .. gtFile) gcf:write(gcode) gcf:write("\n") gcf:close() - + return true end @@ -88,14 +114,14 @@ local function printGcodeFile(printerPath) local gtFile = printerPath .. '/' .. GCODE_TMP_FILE local cmdPath = printerPath .. '/' .. COMMAND_FILE local cmdf,msg = io.open(cmdPath, 'a+') -- 'a+' is important, do not overwrite current contents in any case - + if not cmdf then return nil,msg end if utils.fileSize(cmdf) > 0 then return false end - + log:debug("starting print of gcode in " .. gtFile) cmdf:write('(SENDFILE=' .. gtFile) cmdf:close() - + return true end @@ -105,28 +131,28 @@ end local function stopGcodeFile(printerPath) local cmdPath = printerPath .. '/' .. COMMAND_FILE local cmdf,msg = io.open(cmdPath, 'a+') -- 'a+' is important, do not overwrite current contents in any case - + if not cmdf then return nil,msg end if utils.fileSize(cmdf) > 0 then return false end - + log:debug("stopping print of gcode") cmdf:write('(CANCELFILE') cmdf:close() - + return true end local function isBusy(printerPath) local cmdPath = printerPath .. '/' .. COMMAND_FILE - + if not utils.exists(cmdPath) then return false end - + local f,msg = io.open(cmdPath, 'r') - + if not f then return nil,msg end local size = utils.fileSize(f) f:close() - + return size > 0 end @@ -137,73 +163,47 @@ function M._global(request, response) end --requires id(int) ---accepts with_raw(bool) to include raw printer response +--accepts with_raw(bool) to include raw printer response (currently not implemented) function M.temperature(request, response) - local withRaw = utils.toboolean(request:get("with_raw")) - - local argId,devpath,ultipath = getPrinterDataOrFail(request, response) - if argId == nil then return end - - local f = io.open(ultipath .. '/' .. TEMPERATURE_FILE) - - if not f then - response:setError("could not open temperature file") - response:addData('id', argId) - return - end - - local tempText = f:read('*all') - f:close() - - local hotend, hotendTarget, bed, bedTarget = tempText:match('T:(.*)%s+/(.*)%s+B:(.*)%s/(.*)%s+@.*') - + local argId = request:get("id") + local printer,msg = createPrinterOrFail(argId, response) + if not printer then return end + response:setSuccess() - if withRaw then response:addData('raw', tempText) end - - -- After pressing print it waits until it's at the right temperature. - -- it then stores temperature in the following format - -- T:204.5 E:0 W:? - if(hotend == nil) then - local hotend = tempText:match('T:([%d%.]*).*') - response:addData('hotend', hotend) - else - response:addData('hotend', hotend) - response:addData('bed', bed) - response:addData('hotend_target', hotendTarget) - response:addData('bed_target', bedTarget) - end - - -- get last modified time - local file_attr = lfs.attributes(ultipath .. '/' .. TEMPERATURE_FILE) - local last_mod = file_attr.modification - local last_mod = os.difftime (os.time(),last_mod) - response:addData('last_mod', last_mod) + response:addData('id', argId) + response:addData('hotend', printer:getTemperature()) +-- TODO: reimplement the following fields +-- if withRaw then response:addData('raw', tempText) end +-- response:addData('bed', printer:getBedTemperature()) +-- response:addData('hotend_target', printer:getHotendTargetTemperature()) +-- response:addData('bed_target', printer:getBedTargetTemperature()) +-- response:addData('last_mod', printer:getLastTemperatureUpdate()) end --requires id(int) function M.progress(request, response) local argId,devpath,ultipath = getPrinterDataOrFail(request, response) if argId == nil then return end - + local f = io.open(ultipath .. '/' .. PROGRESS_FILE) - + if not f then response:setError("could not open progress file") response:addData('id', argId) return end - + local tempText = f:read('*all') f:close() local currentLine,numLines = tempText:match('(%d+)/(%d+)') - + response:setSuccess() if(currentLine == nil) then response:addData('printing', false) - else + else response:addData('printing', true) response:addData('current_line', currentLine) response:addData('num_lines', numLines) @@ -221,9 +221,9 @@ end function M.busy(request, response) local argId,devpath,ultipath = getPrinterDataOrFail(request, response) if argId == nil then return end - + local b,msg = isBusy(ultipath) - + if b == nil then response:setError("could not determine printer state") response:addData('msg', msg) @@ -243,10 +243,10 @@ end function M.heatup_POST(request, response) local argId,devpath,ultipath = getPrinterDataOrFail(request, response) if argId == nil then return end - + local gcode = settings.get('printer.autoWarmUpCommand') .. "\n" local rv,msg = sendGcode(ultipath, gcode) - + if rv then response:setSuccess() elseif rv == false then @@ -280,26 +280,26 @@ end function M.print_POST(request, response) local argId,devpath,ultipath = getPrinterDataOrFail(request, response) if argId == nil then return end - + local gtFile = ultipath .. '/' .. GCODE_TMP_FILE local argGcode = request:get("gcode") local argIsFirst = utils.toboolean(request:get("first")) local argIsLast = utils.toboolean(request:get("last")) - + if argGcode == nil or argGcode == '' then response:setError("missing gcode argument") return end - + if argIsFirst == true then log:debug("clearing all gcode in " .. gtFile) response:addData('gcode_clear',true) os.remove(gtFile) end - + local rv,msg - + rv,msg = addToGcodeFile(ultipath, argGcode) if rv == nil then response:setError("could not add gcode") @@ -309,10 +309,10 @@ function M.print_POST(request, response) --NOTE: this does not report the number of lines, but only the block which has just been added response:addData('gcode_append',argGcode:len()) end - + if argIsLast == true then rv,msg = printGcodeFile(ultipath) - + if rv then response:setSuccess() response:addData('gcode_print',true)