I was wondering if there is an API interface to get the GCODE viewer to show the file that is being printed or if a javascript code is available to integrate in an app
Thanks
I was wondering if there is an API interface to get the GCODE viewer to show the file that is being printed or if a javascript code is available to integrate in an app
Thanks
this do? http://docs.octoprint.org/en/master/api/job.html#retrieve-information-about-the-current-job
I just used my octo-client software from npmjs.com to quickly query the currently-running job's filename using NodeJS. I assume that you have Node and npm installed:
cd sites
mkdir octo-getjob && cd octo-getjob
touch octo-getjob
chmod a+x octo-getjob
npm init # When asked for the entry point, indicate "octo-getjob"
npm install --save octo-client
nano node_modules/octo-client/config.js # Edit as necessary with your API key
nano octo-getjob
octo-getjob contents:
#!/usr/bin/env node
var OctoPrint = require('octo-client');
OctoPrint.job(function(response){
console.log(response.job.file.name);
});
./octo-getjob
# Displays "pizero-case-parts-nocutout.gcode"
I am looking for an API that can actually show the graphic of the GCODE just like in ../#gcode view so that I can embed that in my web page
Oh...
I could think of three approaches.
curl
of the Gcode tab page and then remove the HTML that you're not interested in.Could you give an example of the approaches, that will help
Any of the above would be a fair amount of work, to be honest. I attempted to determine a quick-and-dirty method of using awk
at the command line to pare down the page but it's not something that would be easy.
Perhaps others would like to take on the challenge.
Hello from 5 years into the future. I found myself wanting the same functionality as you this morning. I took a look at the plugin source code and decided against trying to integrate with that for the time being, so instead opted to hack some functionality on top.
I made a TamperMonkey script that will automatically activate a fullscreen view of the gcode visualizer if you go to http://octopi.local/?fullscreen=true#gcode. It also adds a button to the gcode visualizer tab so that you can enter fullscreen mode via a button press.
If you don't want to use TamperMonkey you can run the script directly in the console, but TamperMonkey is nice because it will automatically source the script when the page loads. It's all a bit hacky but it works, so that's good enough for now, and maybe someone else can improve it.
// ==UserScript==
// @name octoprint-gcode-visualizer
// @version 0.1
// @description view the octoprint gcode visualizer in full screen when ?fullscreen=true and #gcode hash are in url
// @author gagregrog
// @match http://octopi.local/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
let styles = null;
const zIndex = 999999999;
const start = Date.now();
const elements = {
gcode: null,
container: null,
wrapper: null,
canvas: null,
verticalSlider: null,
horizontalSlider: null,
originalZoomButton: null,
newZoomBtn: document.createElement('button'),
exitFullscreen: document.createElement('button'),
};
info('Initializing...');
init();
function init() {
// get a reference to all of the elements that we need
elements.gcode = document.getElementById('gcode');
elements.container = document.getElementById('canvas_container');
elements.wrapper = elements.container.getElementsByClassName('gcode_canvas_wrapper1')[0];
elements.canvas = document.getElementById('gcode_canvas');
elements.verticalSlider = document.getElementById('gcode_layer_slider');
elements.horizontalSlider = document.getElementById('gcode_command_slider');
for (const label of elements.gcode.getElementsByTagName('label')) {
if (!elements.originalZoomButton && label.textContent?.includes('Zoom in on model')) {
elements.originalZoomButton = label.getElementsByTagName('input')[0];
}
}
// if any of the elements aren't found, try again in a moment
if ([elements.container, elements.wrapper, elements.canvas, elements.verticalSlider, elements.horizontalSlider, elements.originalZoomButton].some(ele => !ele)) {
// abort if not found after 10 seconds
if (Date.now() - start < 10000) {
setTimeout(init, 100);
} else {
err('Could not find the required elements!');
}
return;
}
initializeButtonsAndListeners();
initializeStyles();
info('Initialized!');
stashOriginalStyles();
enableFullscreenIfQueryPresent(true);
}
function initializeButtonsAndListeners() {
addButtons();
// listener to update the dimensions if the window is resized
window.addEventListener('resize', () => {
updateDimensions();
enableFullscreenIfQueryPresent(false);
}, true);
// let new button click old button to trigger centering of the image
elements.newZoomBtn.addEventListener('click', () => elements.originalZoomButton.click());
}
function initializeStyles() {
const dim = getMaxDim();
// capture overrides and original styles to toggle back and forth
styles = [
{
element: document.body,
styles: [
{ key: 'overflow', override: 'hidden', },
],
},
{
element: elements.container,
styles: [
{ key: 'background', override: 'black', },
{ key: 'position', override: 'fixed', },
{ key: 'width', override: '100%', },
{ key: 'height', override: '100%', },
{ key: 'top', override: 0, },
{ key: 'left', override: 0, },
{ key: 'zIndex', override: zIndex, },
],
},
{
element: elements.wrapper,
styles: [
{ key: 'width', override: '100%', },
{ key: 'height', override: '100%', },
],
},
{
element: elements.canvas,
styles: [
{ key: 'height', override: `${dim}px`, },
{ key: 'width', override: `${dim}px`, },
],
},
{
element: elements.verticalSlider,
styles: [
{ key: 'top', override: '15px', },
{ key: 'right', override: '15px', },
{ key: 'maxHeight', override: 'calc(100% - 75px)', },
],
},
{
element: elements.horizontalSlider,
styles: [
{ key: 'bottom', override: '15px', },
{ key: 'left', override: '27px', },
{ key: 'position', override: 'fixed', },
{ key: 'zIndex', override: zIndex + 1, },
{ key: 'maxWidth', override: 'calc(100% - 54px)', },
],
},
];
}
function updateDimensions() {
const dim = getMaxDim();
const canvasStylesGroup = styles.find(({element}) => element === elements.canvas);
canvasStylesGroup.styles.forEach(style => {
style.override = `${dim}px`;
});
}
function addButtons() {
addEnterFullscreenButton();
addExitFullscreenButton();
addZoomButton();
}
function addEnterFullscreenButton() {
const gcode = document.getElementById('gcode');
for (const p of gcode.getElementsByTagName('p')) {
if (p.getElementsByTagName('button').length && p.textContent.includes('Reset viewport')) {
const fs = document.createElement('button');
fs.classList.add('btn');
fs.classList.add('btn-block');
fs.textContent = 'Fullscreen';
fs.addEventListener('click', () => {
const newUrl = new URL(location);
newUrl.searchParams.set('fullscreen', 'true');
history.replaceState({}, '', newUrl);
enableFullscreenStyles(true);
});
p.prepend(fs);
break;
}
}
}
function addExitFullscreenButton() {
elements.exitFullscreen.style.display = 'none';
elements.exitFullscreen.style.position = 'fixed';
elements.exitFullscreen.style.top = '45px';
elements.exitFullscreen.style.left = '15px';
elements.exitFullscreen.style.zIndex = zIndex + 1;
elements.exitFullscreen.style.color = 'black';
elements.exitFullscreen.textContent = 'Exit Fullscreen';
elements.exitFullscreen.addEventListener('click', () => {
info('Exiting fullscreen');
disableFullscreenStyles();
const newUrl = new URL(location);
newUrl.searchParams.delete('fullscreen');
history.replaceState({}, '', newUrl);
});
document.body.appendChild(elements.exitFullscreen);
}
function addZoomButton() {
elements.newZoomBtn.style.display = 'none';
elements.newZoomBtn.style.position = 'fixed';
elements.newZoomBtn.style.top = '15px';
elements.newZoomBtn.style.left = '15px';
elements.newZoomBtn.style.zIndex = zIndex + 1;
elements.newZoomBtn.style.color = 'black';
elements.newZoomBtn.textContent = 'Zoom and Center';
// event listener will be added when initialized
document.body.appendChild(elements.newZoomBtn);
}
function stashOriginalStyles() {
styles.forEach(styleGroup => {
styleGroup.styles.forEach((stash) => {
stash.original = styleGroup.element.style[stash.key];
});
});
}
function enableFullscreenIfQueryPresent(shouldAnnounce) {
// only enable fullscreen if query string is set and hash matches
const url = new URL(window.location);
if (url.searchParams.get('fullscreen') === 'true' && url.hash === '#gcode') {
enableFullscreenStyles(shouldAnnounce);
}
}
function enableFullscreenStyles(shouldAnnounce) {
if (shouldAnnounce) {
info('Entering fullscreen!');
}
// activate all overrides
styles.forEach(styleGroup => {
styleGroup.styles.forEach((stash) => {
styleGroup.element.style[stash.key] = stash.override;
});
});
// show the additional buttons
elements.exitFullscreen.style.display = 'block';
elements.newZoomBtn.style.display = 'block';
}
function disableFullscreenStyles() {
// hide the additional buttons
elements.exitFullscreen.style.display = 'none';
elements.newZoomBtn.style.display = 'none';
// activate all original styles
styles.forEach(styleGroup => {
styleGroup.styles.forEach((stash) => {
styleGroup.element.style[stash.key] = stash.original;
});
});
}
function getMaxDim() {
// determine the maximum dimensions
const vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0);
const vh = Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0);
const dim = Math.min(vw, vh);
return dim;
}
function info() {
console.log('[FULLSCREEN_GCODE_VISUALIZER]', ...arguments);
}
function err() {
console.error('[FULLSCREEN_GCODE_VISUALIZER]', ...arguments);
}
})();