diff --git a/src/components/Panels/Macros.js b/src/components/Panels/Macros.js index 6fa50201..0e90c242 100644 --- a/src/components/Panels/Macros.js +++ b/src/components/Panels/Macros.js @@ -31,6 +31,7 @@ import { files, variablesList, } from "../../targets" +import { buildEsp700Command } from "../../targets/helpers" /* * Local const @@ -85,9 +86,7 @@ const MacrosPanel = () => { const processMacro = (action, type) => { switch (type) { case "FS": - //[ESP700] //ESP700 should send status to telnet / websocket - //Todo: handle response from ESP700 - sendCommand("[ESP700]" + action) + sendCommand(buildEsp700Command(action)) break case "SD": //get command accoring target FW diff --git a/src/components/Panels/Status.js b/src/components/Panels/Status.js index b4477a31..358e3c19 100644 --- a/src/components/Panels/Status.js +++ b/src/components/Panels/Status.js @@ -19,7 +19,13 @@ import { Fragment, h } from "preact" import { useRef } from "preact/hooks" import { T } from "../Translations" -import { Layers, PlayCircle, PauseCircle, StopCircle } from "preact-feather" +import { + Layers, + PlayCircle, + PauseCircle, + StopCircle, + CheckCircle, +} from "preact-feather" import { useUiContext, useUiContextFn } from "../../contexts" import { useTargetContext } from "../../targets" import { ButtonImg, FullScreenButton, CloseButton, ContainerHelper } from "../Controls" @@ -64,6 +70,61 @@ const TimeControl = ({ label, time }) => { ) } +const toTimeObject = (seconds) => { + const value = parseInt(seconds || 0) + if (!value || value < 0) return null + return { + year: null, + day: Math.floor((value % (86400 * 30)) / 86400), + hour: Math.floor((value % 86400) / 3600), + min: Math.floor((value % 3600) / 60), + sec: Math.floor(value % 60), + } +} + +const getStreamView = (streamStatus) => { + if (!streamStatus || !streamStatus.status) return null + const progress = + typeof streamStatus.m73_progress !== "undefined" + ? parseFloat(streamStatus.m73_progress).toFixed(2) + : streamStatus.processed && streamStatus.total + ? Math.round( + (streamStatus.processed / streamStatus.total) * 100 + ).toFixed(2) + : null + + const printTime = + typeof streamStatus.m73_elapsed !== "undefined" + ? toTimeObject(streamStatus.m73_elapsed) + : toTimeObject( + streamStatus.elapsed + ? Math.floor(streamStatus.elapsed / 1000) + : 0 + ) + + let printLeftTime = null + if (typeof streamStatus.m73_remaining !== "undefined") { + printLeftTime = toTimeObject(streamStatus.m73_remaining) + } else if ( + streamStatus.elapsed && + progress && + parseFloat(progress) > 0 && + parseFloat(progress) < 100 + ) { + const timeLeft = + ((100 - parseFloat(progress)) / parseFloat(progress)) * + streamStatus.elapsed + printLeftTime = toTimeObject(Math.floor(timeLeft / 1000)) + } + + return { + ...streamStatus, + progress, + printTime, + printLeftTime, + } +} + /* * Local const * @@ -71,6 +132,7 @@ const TimeControl = ({ label, time }) => { const StatusControls = () => { const { streamStatus, status } = useTargetContext() + const streamView = getStreamView(streamStatus) if (!useUiContextFn.getValue("showstatuspanel")) return null //console.log("streamStatus") //console.log(streamStatus) @@ -78,38 +140,33 @@ const StatusControls = () => { //console.log(status) return ( - {streamStatus && - streamStatus.status && - streamStatus.status != "no stream" && ( + {streamView && streamView.status && streamView.status != "no stream" && (
- {T(streamStatus.status)} + {T(streamView.status)}
- {streamStatus.name && - streamStatus.name.length > 0 && ( + {streamView.name && streamView.name.length > 0 && (
- {streamStatus.name} + {streamView.name}
)} - {streamStatus && - streamStatus.status && - streamStatus.status != "no stream" && ( + {streamView.status && streamView.status != "no stream" && (
- {streamStatus.progress}% + {streamView.progress}%
)} @@ -178,37 +235,28 @@ const StatusPanel = () => { depend: ["sd"], buttons: [ { - cmd: () => { - if (status.printState && status.printState.printing) { - return "sdresumecmd" - } - return "[ESP701]RESUME" - }, + cmd: () => "[ESP701]action=RESUME", depend: { streamStatus: ["pause"], status: [] }, icon: , desc: T("P99"), }, { - cmd: () => { - if (status.printState && status.printState.printing) { - return "sdpausecmd" - } - return "[ESP701]PAUSE" - }, + cmd: () => "[ESP701]action=PAUSE", depend: { streamStatus: ["processing"], status: [] }, icon: , desc: T("P98"), }, { - cmd: () => { - if (status.printState && status.printState.printing) { - return "sdstopcmd" - } - return "[ESP701]ABORT" - }, + cmd: () => "[ESP701]action=ABORT", icon: , desc: T("P100"), }, + { + cmd: () => "[ESP701]action=CLEAR_ERROR", + depend: { hasCode: true, status: [] }, + icon: , + desc: T("S206"), + }, ], }, { @@ -283,6 +331,9 @@ const StatusPanel = () => { } const isVisible = (button) => { if (button.depend) { + if (button.depend.hasCode && !(streamStatus && streamStatus.code)) { + return false + } if ( streamStatus && streamStatus.status && @@ -319,8 +370,7 @@ const StatusPanel = () => { {((status.printState && status.printState.printing) || (streamStatus && streamStatus.status && - streamStatus.status != "no stream" && - streamStatus.name != "")) && + streamStatus.status != "no stream")) && deviceList.map((device) => { if ( !device.depend.every((d) => @@ -350,14 +400,23 @@ const StatusPanel = () => { console.log( button.cmd() ) + const buttonCommand = + button.cmd() const cmd = - status.printState && - status.printState - .printing - ? useUiContextFn.getValue( - button.cmd() - ) - : button.cmd() + buttonCommand && + buttonCommand.startsWith( + "[ESP" + ) + ? buttonCommand + : status.printState && + status + .printState + .printing + ? useUiContextFn.getValue( + buttonCommand + ) + : buttonCommand + if (!cmd) return const cmds = cmd.split("\n") cmds.forEach((cmd) => { diff --git a/src/targets/CNC/GRBL/DIRECTSD-source.js b/src/targets/CNC/GRBL/DIRECTSD-source.js index 63d7bff6..be902891 100644 --- a/src/targets/CNC/GRBL/DIRECTSD-source.js +++ b/src/targets/CNC/GRBL/DIRECTSD-source.js @@ -19,7 +19,7 @@ */ import { h } from "preact" import { sortedFilesList, formatStatus } from "../../../components/Helpers" -import { canProcessFile } from "../../helpers" +import { canProcessFile, buildEsp700CommandFromParts } from "../../helpers" import { useUiContextFn } from "../../../contexts" const capabilities = { @@ -106,12 +106,7 @@ const commands = { play: (path, filename) => { return { type: "cmd", - cmd: - "[ESP700]/SD" + - path + - (path == "/" ? "" : "/") + - filename + - "\n", + cmd: buildEsp700CommandFromParts("/SD", path, filename) + "\n", } }, } diff --git a/src/targets/Printer3D/Marlin/DIRECTSD-source.js b/src/targets/Printer3D/Marlin/DIRECTSD-source.js index a162e02c..01c67600 100644 --- a/src/targets/Printer3D/Marlin/DIRECTSD-source.js +++ b/src/targets/Printer3D/Marlin/DIRECTSD-source.js @@ -18,7 +18,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ import { h } from "preact" -import { canProcessFile } from "../../helpers" +import { canProcessFile, buildEsp700CommandFromParts } from "../../helpers" import { sortedFilesList, formatStatus } from "../../../components/Helpers" import { useUiContextFn, useSettingsContextFn } from "../../../contexts" @@ -129,16 +129,9 @@ const commands = { useSettingsContextFn.getValue("Streaming") == "Enabled" && useSettingsContextFn.getValue("SDConnection") == "direct" ) { - const fullpath = ( - "/sd" + - path + - (path.endsWith("/") ? "" : "/") + - filename - ).replaceAll("//", "/") - const cmd = "[ESP700]stream=" + fullpath return { type: "cmd", - cmd, + cmd: buildEsp700CommandFromParts("/SD", path, filename), } } else { const spath = ( diff --git a/src/targets/Printer3D/Marlin/FLASH-source.js b/src/targets/Printer3D/Marlin/FLASH-source.js index 494d0ac1..b4bdb3c7 100644 --- a/src/targets/Printer3D/Marlin/FLASH-source.js +++ b/src/targets/Printer3D/Marlin/FLASH-source.js @@ -19,7 +19,7 @@ */ import { h } from "preact" import { sortedFilesList, formatStatus } from "../../../components/Helpers" -import { canProcessFile } from "../../helpers" +import { canProcessFile, buildEsp700CommandFromParts } from "../../helpers" import { useUiContextFn, useSettingsContextFn } from "../../../contexts" const capabilities = { Process: (path, filename) => { @@ -120,11 +120,9 @@ const commands = { useSettingsContextFn.getValue("Streaming") == "Enabled" && useSettingsContextFn.getValue("SDConnection") == "direct" ) { - let fullpath = - "/fs" + path + (path.endsWith("/") ? "" : "/") + filename return { type: "cmd", - cmd: "[ESP700]stream=" + fullpath.replaceAll(" ", " "), + cmd: buildEsp700CommandFromParts("/FS", path, filename), } } else { return { diff --git a/src/targets/Printer3D/Marlin/TargetContext.js b/src/targets/Printer3D/Marlin/TargetContext.js index 0d3db534..75e0788a 100644 --- a/src/targets/Printer3D/Marlin/TargetContext.js +++ b/src/targets/Printer3D/Marlin/TargetContext.js @@ -261,45 +261,8 @@ const TargetContextProvider = ({ children }) => { console.log("response", data) if (isStreamingStatus(data)) { const preStatus = getStreamingStatus(data) - const name = preStatus.name const status = preStatus.status - const progress = - preStatus.processed && preStatus.total - ? Math.round( - (preStatus.processed / preStatus.total) * 100 - ).toFixed(2) - : null - const printTime = {} - - let time_elapsed = preStatus.elapsed - printTime.sec = Math.floor(time_elapsed / 1000) - printTime.min = Math.floor(printTime.sec / 60) - printTime.sec = printTime.sec % 60 - printTime.hour = Math.floor(printTime.min / 60) - printTime.min = printTime.min % 60 - printTime.day = Math.floor(printTime.hour / 24) - printTime.hour = printTime.hour % 24 - const printLeftTime = {} - if (preStatus.elapsed && progress && progress < 100) { - const timeLeft = - ((100 - progress) / progress) * preStatus.elapsed - - printLeftTime.sec = Math.floor(timeLeft / 1000) - printLeftTime.min = Math.floor(printLeftTime.sec / 60) - printLeftTime.sec = printLeftTime.sec % 60 - printLeftTime.hour = Math.floor(printLeftTime.min / 60) - printLeftTime.min = printLeftTime.min % 60 - printLeftTime.day = Math.floor(printLeftTime.hour / 24) - printLeftTime.hour = printLeftTime.hour % 24 - } - const fullstatus = { - status, - progress, - name, - printTime, - printLeftTime, - } - setStreamStatus(fullstatus) + setStreamStatus(preStatus) if (status != "no stream") { setStatus({ printState: null }) } diff --git a/src/targets/Printer3D/Marlin/preferences.json b/src/targets/Printer3D/Marlin/preferences.json index 463a4df0..c5ef3840 100644 --- a/src/targets/Printer3D/Marlin/preferences.json +++ b/src/targets/Printer3D/Marlin/preferences.json @@ -59,7 +59,7 @@ { "id": "samplepolling", "name": "3s", - "cmds": "M105", + "cmds": "M105;[ESP701]json", "refreshtime": "3000" } ] diff --git a/src/targets/SandTable/GRBL/DIRECTSD-source.js b/src/targets/SandTable/GRBL/DIRECTSD-source.js index a988b5e8..a63289fb 100644 --- a/src/targets/SandTable/GRBL/DIRECTSD-source.js +++ b/src/targets/SandTable/GRBL/DIRECTSD-source.js @@ -19,7 +19,7 @@ */ import { h } from "preact" import { sortedFilesList, formatStatus } from "../../../components/Helpers" -import { canProcessFile } from "../../helpers" +import { canProcessFile, buildEsp700CommandFromParts } from "../../helpers" const capabilities = { Process: (path, filename) => { @@ -103,12 +103,7 @@ const commands = { play: (path, filename) => { return { type: "cmd", - cmd: - "[ESP700]/SD" + - path + - (path == "/" ? "" : "/") + - filename + - "\n", + cmd: buildEsp700CommandFromParts("/SD", path, filename) + "\n", } }, } diff --git a/src/targets/helpers.js b/src/targets/helpers.js index 430dbf91..07fbedf2 100644 --- a/src/targets/helpers.js +++ b/src/targets/helpers.js @@ -34,4 +34,35 @@ const canProcessFile = (filename) => { return false } -export { canProcessFile } +const normalizeEsp3dFilePath = (filePath) => { + if (!filePath) { + return "" + } + + let normalizedPath = filePath.trim().replaceAll("\\", "/") + if (!normalizedPath.startsWith("/")) { + normalizedPath = "/" + normalizedPath + } + + normalizedPath = normalizedPath.replace(/^\/(sd|fs)(?=\/|$)/i, (_, root) => { + return "/" + root.toUpperCase() + }) + + return normalizedPath.replace(/\/+/g, "/") +} + +const buildEsp700Command = (filePath) => { + return "[ESP700]" + normalizeEsp3dFilePath(filePath) +} + +const buildEsp700CommandFromParts = (rootPath, path, filename) => { + const basePath = rootPath + path + (path.endsWith("/") ? "" : "/") + filename + return buildEsp700Command(basePath) +} + +export { + canProcessFile, + normalizeEsp3dFilePath, + buildEsp700Command, + buildEsp700CommandFromParts, +}