allow spool select / override for bbl print jobs
This commit is contained in:
parent
4effee7c0e
commit
0fb9607bf2
5 changed files with 104 additions and 30 deletions
|
|
@ -13,7 +13,7 @@ self.kiri.load(api => {
|
||||||
let monitors = [];
|
let monitors = [];
|
||||||
let video_on = false;
|
let video_on = false;
|
||||||
let bound, device, printers, select, selected, conn_alert, export_select;
|
let bound, device, printers, select, selected, conn_alert, export_select;
|
||||||
let btn_del, in_host, in_code, in_serial, filelist;
|
let btn_del, in_host, in_code, in_serial, filelist, print_ams_select = 'auto';
|
||||||
let ptype, host, password, serial, amsmap, socket = {
|
let ptype, host, password, serial, amsmap, socket = {
|
||||||
open: false,
|
open: false,
|
||||||
q: [],
|
q: [],
|
||||||
|
|
@ -243,6 +243,22 @@ self.kiri.load(api => {
|
||||||
h.option({ _: 'none', value: '255' }),
|
h.option({ _: 'none', value: '255' }),
|
||||||
...options
|
...options
|
||||||
]);
|
]);
|
||||||
|
[ "print-bambu-spool", "bbl_file_spool" ].forEach(dropdown => {
|
||||||
|
h.bind($(dropdown),[
|
||||||
|
h.option({ _: 'external', value: '', _selected: print_ams_select === '' }),
|
||||||
|
h.option({ _: 'ams auto', value: 'auto', _selected: print_ams_select === 'auto' }),
|
||||||
|
...trays.map(tray => {
|
||||||
|
return h.option({
|
||||||
|
_: `ams tray ${tray.id}`,
|
||||||
|
_selected: print_ams_select === tray.id,
|
||||||
|
value: tray.id,
|
||||||
|
});
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
$(dropdown).onchange = (ev) => {
|
||||||
|
print_ams_select = ev.target.value;
|
||||||
|
};
|
||||||
|
});
|
||||||
let tdiv = $('bbl_ams_trays');
|
let tdiv = $('bbl_ams_trays');
|
||||||
tdiv.setAttribute("style",[
|
tdiv.setAttribute("style",[
|
||||||
"gap: 5px;",
|
"gap: 5px;",
|
||||||
|
|
@ -263,6 +279,9 @@ self.kiri.load(api => {
|
||||||
})))
|
})))
|
||||||
} else {
|
} else {
|
||||||
$('bbl_ams_tray').innerHTML = '';
|
$('bbl_ams_tray').innerHTML = '';
|
||||||
|
$('bbl_file_spool').innerHTML = '';
|
||||||
|
$('print-bambu-spool').innerHTML = '';
|
||||||
|
print_ams_select = 'auto';
|
||||||
}
|
}
|
||||||
let state = (gcode_state || 'unknown').toLowerCase();
|
let state = (gcode_state || 'unknown').toLowerCase();
|
||||||
$('bbl_noz').value = nozzle_diameter || '';
|
$('bbl_noz').value = nozzle_diameter || '';
|
||||||
|
|
@ -431,9 +450,17 @@ self.kiri.load(api => {
|
||||||
|
|
||||||
function file_print(path) {
|
function file_print(path) {
|
||||||
if (selected?.rec?.host && path) {
|
if (selected?.rec?.host && path) {
|
||||||
|
let spool = print_ams_select;
|
||||||
let { host, code, serial } = selected.rec;
|
let { host, code, serial } = selected.rec;
|
||||||
console.log({ file_print: path, host, code, serial, amsmap });
|
console.log({ file_print: path, host, code, serial, spool, amsmap });
|
||||||
socket.send({ cmd: "file-print", path, host, code, serial, amsmap });
|
socket.send({
|
||||||
|
cmd: "file-print",
|
||||||
|
path,
|
||||||
|
host,
|
||||||
|
code,
|
||||||
|
serial,
|
||||||
|
amsmap: spool === 'auto' && amsmap ? amsmap : spool
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -743,16 +770,11 @@ self.kiri.load(api => {
|
||||||
h.label('date'),
|
h.label('date'),
|
||||||
h.input({ id: "bbl_file_date", size: 12, readonly })
|
h.input({ id: "bbl_file_date", size: 12, readonly })
|
||||||
]),
|
]),
|
||||||
|
h.div({ class: "var-row" }, [
|
||||||
|
h.label('spool'),
|
||||||
|
h.select({ id: "bbl_file_spool" })
|
||||||
|
]),
|
||||||
h.div({ class: "grow" }),
|
h.div({ class: "grow" }),
|
||||||
h.button({
|
|
||||||
_: 'delete',
|
|
||||||
id: "bbl_file_delete",
|
|
||||||
class: "f-col a-center t-center",
|
|
||||||
disabled: true,
|
|
||||||
onclick() {
|
|
||||||
console.log({ deleting: selected.file.path });
|
|
||||||
file_delete(selected.file.path);
|
|
||||||
}}),
|
|
||||||
h.button({
|
h.button({
|
||||||
_: 'print',
|
_: 'print',
|
||||||
id: "bbl_file_print",
|
id: "bbl_file_print",
|
||||||
|
|
@ -763,6 +785,15 @@ self.kiri.load(api => {
|
||||||
file_print(selected.file.path);
|
file_print(selected.file.path);
|
||||||
api.alerts.show(`printing: ${selected.file.path}`,2);
|
api.alerts.show(`printing: ${selected.file.path}`,2);
|
||||||
}}),
|
}}),
|
||||||
|
h.button({
|
||||||
|
_: 'delete',
|
||||||
|
id: "bbl_file_delete",
|
||||||
|
class: "f-col a-center t-center",
|
||||||
|
disabled: true,
|
||||||
|
onclick() {
|
||||||
|
console.log({ deleting: selected.file.path });
|
||||||
|
file_delete(selected.file.path);
|
||||||
|
}}),
|
||||||
]),
|
]),
|
||||||
h.div({ class: "t-body t-inset f-col gap3 pad4" }, [
|
h.div({ class: "t-body t-inset f-col gap3 pad4" }, [
|
||||||
h.label({ class: "set-header dev-sel" }, [
|
h.label({ class: "set-header dev-sel" }, [
|
||||||
|
|
@ -796,8 +827,8 @@ self.kiri.load(api => {
|
||||||
select.onchange = (ev => printer_select(select.value));
|
select.onchange = (ev => printer_select(select.value));
|
||||||
filelist.onchange = (ev => {
|
filelist.onchange = (ev => {
|
||||||
let file = selected.file = selected.status.files[filelist.selectedIndex];
|
let file = selected.file = selected.status.files[filelist.selectedIndex];
|
||||||
$('bbl_file_size').value = file.size;
|
$('bbl_file_size').value = file?.size ?? '';
|
||||||
$('bbl_file_date').value = file.date;
|
$('bbl_file_date').value = file?.date ?? '';
|
||||||
$('bbl_file_delete').disabled =
|
$('bbl_file_delete').disabled =
|
||||||
$('bbl_file_print').disabled = false;
|
$('bbl_file_print').disabled = false;
|
||||||
});
|
});
|
||||||
|
|
@ -876,29 +907,32 @@ self.kiri.load(api => {
|
||||||
api.modal.show('bambu');
|
api.modal.show('bambu');
|
||||||
}
|
}
|
||||||
devlist.onchange = () => {
|
devlist.onchange = () => {
|
||||||
let info = printers[devlist.value];
|
let info = printers[devlist.value] || {};
|
||||||
host = info.host;
|
host = info.host;
|
||||||
ptype = info.type;
|
ptype = info.type;
|
||||||
serial = info.serial;
|
serial = info.serial;
|
||||||
password = info.code;
|
password = info.code;
|
||||||
export_select = devlist.value;
|
export_select = devlist.value;
|
||||||
|
$('print-bambu-spool').innerHMTL = '<option>loading...</option>';
|
||||||
$('print-bambu-1').disabled =
|
$('print-bambu-1').disabled =
|
||||||
$('print-bambu-2').disabled =
|
$('print-bambu-2').disabled =
|
||||||
(host && serial && password) ? false : true;
|
(host && serial && password) ? false : true;
|
||||||
get_ams_map(settings);
|
get_ams_map(settings);
|
||||||
|
printer_select(export_select);
|
||||||
console.log({ bambu: serial, ptype, host, amsmap });
|
console.log({ bambu: serial, ptype, host, amsmap });
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function send(filename, gcode, start) {
|
function send(filename, gcode, start) {
|
||||||
|
const spool = print_ams_select;
|
||||||
const baseUrl = '/api/bambu_send';
|
const baseUrl = '/api/bambu_send';
|
||||||
const url = new URL(baseUrl, window.location.origin);
|
const url = new URL(baseUrl, window.location.origin);
|
||||||
url.searchParams.append('host', host);
|
url.searchParams.append('host', host);
|
||||||
url.searchParams.append('code', password);
|
url.searchParams.append('code', password);
|
||||||
url.searchParams.append('filename', filename);
|
url.searchParams.append('filename', filename);
|
||||||
url.searchParams.append('serial', serial);
|
url.searchParams.append('serial', serial);
|
||||||
url.searchParams.append('ams', amsmap);
|
|
||||||
url.searchParams.append('start', start ?? false);
|
url.searchParams.append('start', start ?? false);
|
||||||
|
url.searchParams.append('ams', spool === 'auto' && amsmap ? amsmap : spool);
|
||||||
|
|
||||||
const alert = api.alerts.show('Sending to Bambu Printer');
|
const alert = api.alerts.show('Sending to Bambu Printer');
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ class FrameStream extends EventEmitter {
|
||||||
const encoder = new TextEncoder();
|
const encoder = new TextEncoder();
|
||||||
const userBytes = encoder.encode('bblp');
|
const userBytes = encoder.encode('bblp');
|
||||||
const codeBytes = encoder.encode(code);
|
const codeBytes = encoder.encode(code);
|
||||||
|
const useCA = false;
|
||||||
|
|
||||||
view.setInt32(0, 0x0040, true);
|
view.setInt32(0, 0x0040, true);
|
||||||
view.setInt32(4, 0x3000, true);
|
view.setInt32(4, 0x3000, true);
|
||||||
|
|
@ -25,12 +26,16 @@ class FrameStream extends EventEmitter {
|
||||||
new Uint8Array(abuf, 0x30, codeBytes.length).set(codeBytes);
|
new Uint8Array(abuf, 0x30, codeBytes.length).set(codeBytes);
|
||||||
|
|
||||||
let frame;
|
let frame;
|
||||||
const remoteSocket = this.#remoteSocket = tls.connect({
|
const remoteSocket = this.#remoteSocket = tls.connect(Object.assign({}, {
|
||||||
host,
|
host,
|
||||||
port: 6000,
|
port: 6000
|
||||||
|
}, useCA ? {
|
||||||
ca: bblCA,
|
ca: bblCA,
|
||||||
servername: serial
|
servername: serial
|
||||||
}, () => {
|
} : {
|
||||||
|
rejectUnauthorized: false,
|
||||||
|
checkServerIdentity: () => {}
|
||||||
|
}), () => {
|
||||||
// send authentication to start jpeg frame stream
|
// send authentication to start jpeg frame stream
|
||||||
remoteSocket.write(Buffer.from(abuf));
|
remoteSocket.write(Buffer.from(abuf));
|
||||||
this.emit('connect', host);
|
this.emit('connect', host);
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ module.exports = async (server) => {
|
||||||
const mcache = {};
|
const mcache = {};
|
||||||
const wsopen = [];
|
const wsopen = [];
|
||||||
const found = {};
|
const found = {};
|
||||||
|
const useCA = false;
|
||||||
const debug = false;
|
const debug = false;
|
||||||
|
|
||||||
class MQTT {
|
class MQTT {
|
||||||
|
|
@ -21,12 +22,15 @@ module.exports = async (server) => {
|
||||||
#frames;
|
#frames;
|
||||||
#topic_report;
|
#topic_report;
|
||||||
#topic_request;
|
#topic_request;
|
||||||
#options = {
|
#options = Object.assign({}, {
|
||||||
protocol: 'mqtts',
|
protocol: 'mqtts',
|
||||||
port: 8883,
|
port: 8883,
|
||||||
username: 'bblp',
|
username: 'bblp',
|
||||||
|
}, useCA ? {
|
||||||
ca: bblCA
|
ca: bblCA
|
||||||
}
|
} : {
|
||||||
|
rejectUnauthorized: false
|
||||||
|
});
|
||||||
|
|
||||||
constructor(host, code, serial, onready, onerror, onmessage) {
|
constructor(host, code, serial, onready, onerror, onmessage) {
|
||||||
this.#options.host = host;
|
this.#options.host = host;
|
||||||
|
|
@ -74,7 +78,10 @@ module.exports = async (server) => {
|
||||||
|
|
||||||
keepalive() {
|
keepalive() {
|
||||||
clearTimeout(this.#timer);
|
clearTimeout(this.#timer);
|
||||||
this.#timer = setTimeout(() => { this.end() }, 30000);
|
this.#timer = setTimeout(() => {
|
||||||
|
util.log('keepalive expired', this.#serial);
|
||||||
|
this.end();
|
||||||
|
}, 300000);
|
||||||
}
|
}
|
||||||
|
|
||||||
keepconn() {
|
keepconn() {
|
||||||
|
|
@ -102,7 +109,7 @@ module.exports = async (server) => {
|
||||||
|
|
||||||
end() {
|
end() {
|
||||||
if (this.#client) {
|
if (this.#client) {
|
||||||
debug && util.log('mqtt end', this.#serial);
|
util.log('mqtt end', this.#serial);
|
||||||
this.#client.end();
|
this.#client.end();
|
||||||
this.#client = undefined;
|
this.#client = undefined;
|
||||||
}
|
}
|
||||||
|
|
@ -144,7 +151,7 @@ module.exports = async (server) => {
|
||||||
const host = args.host || "localhost";
|
const host = args.host || "localhost";
|
||||||
const user = args.user || "bblp";
|
const user = args.user || "bblp";
|
||||||
const password = args.password || args.code || '';
|
const password = args.password || args.code || '';
|
||||||
// client.ftp.verbose = true;
|
client.ftp.verbose = debug;
|
||||||
try {
|
try {
|
||||||
await client.access({
|
await client.access({
|
||||||
port,
|
port,
|
||||||
|
|
@ -152,7 +159,12 @@ module.exports = async (server) => {
|
||||||
user,
|
user,
|
||||||
password,
|
password,
|
||||||
secure: "implicit",
|
secure: "implicit",
|
||||||
secureOptions: { ca: bblCA, servername: args.serial }
|
secureOptions: useCA ? {
|
||||||
|
ca: bblCA,
|
||||||
|
servername: args.serial
|
||||||
|
} : {
|
||||||
|
rejectUnauthorized: false
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
util.log({ ftp_error: error });
|
util.log({ ftp_error: error });
|
||||||
|
|
@ -219,10 +231,10 @@ module.exports = async (server) => {
|
||||||
vibration_cali: false
|
vibration_cali: false
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (amsmap) {
|
if (amsmap && amsmap !== 'auto') {
|
||||||
cmd.print.ams_mapping = amsmap.split(',').map(v => parseInt(v));
|
cmd.print.ams_mapping = amsmap.split(',').map(v => parseInt(v));
|
||||||
}
|
}
|
||||||
debug && util.log({ file_print: cmd });
|
util.log({ file_print: cmd });
|
||||||
get_mqtt(host, code, serial, message => {
|
get_mqtt(host, code, serial, message => {
|
||||||
debug && util.log('mqtt_recv', message);
|
debug && util.log('mqtt_recv', message);
|
||||||
wsend({ serial, message });
|
wsend({ serial, message });
|
||||||
|
|
@ -404,7 +416,7 @@ module.exports = async (server) => {
|
||||||
if_mqtt(serial, direct);
|
if_mqtt(serial, direct);
|
||||||
break;
|
break;
|
||||||
case "frames":
|
case "frames":
|
||||||
util.log('request frames', serial, frames);
|
debug && util.log('request frames', serial, frames);
|
||||||
mcache[serial]?.set_frames(frames);
|
mcache[serial]?.set_frames(frames);
|
||||||
break;
|
break;
|
||||||
case "keepalive":
|
case "keepalive":
|
||||||
|
|
|
||||||
|
|
@ -529,7 +529,7 @@ function exportGCodeDialog(gcode, sections, info, names) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function gen3mf(then, ptype = 'unknown') {
|
function gen3mf(then, ptype = 'unknown') {
|
||||||
console.log({ gen3mf_target: ptype });
|
console.log({ gen3mf_printer_type: ptype });
|
||||||
let now = new Date();
|
let now = new Date();
|
||||||
let ymd = [
|
let ymd = [
|
||||||
now.getFullYear(),
|
now.getFullYear(),
|
||||||
|
|
@ -583,6 +583,27 @@ function exportGCodeDialog(gcode, sections, info, names) {
|
||||||
'</Relationships>'
|
'</Relationships>'
|
||||||
].join('\n')
|
].join('\n')
|
||||||
},{
|
},{
|
||||||
|
// name: `Metadata/plate_1.json`,
|
||||||
|
// data: JSON.toString({
|
||||||
|
// "bbox_all": [ 115.199992, 115.199992, 140.799992, 140.799992 ],
|
||||||
|
// "bbox_objects": [
|
||||||
|
// {
|
||||||
|
// "area": 655.3599853515625,
|
||||||
|
// "bbox": [ 115.199992, 115.199992, 140.799992, 140.799992 ],
|
||||||
|
// "id": 42,
|
||||||
|
// "layer_height": 0.25,
|
||||||
|
// "name": "Cube"
|
||||||
|
// }
|
||||||
|
// ],
|
||||||
|
// "bed_type": "textured_plate",
|
||||||
|
// "filament_colors": ["#FFFFFF"],
|
||||||
|
// "filament_ids": [0],
|
||||||
|
// "first_extruder": 0,
|
||||||
|
// "is_seq_print": false,
|
||||||
|
// "nozzle_diameter": 0.6,
|
||||||
|
// "version": 2
|
||||||
|
// })
|
||||||
|
// },{
|
||||||
name: `Metadata/model_settings.config`,
|
name: `Metadata/model_settings.config`,
|
||||||
data: [
|
data: [
|
||||||
'<?xml version="1.0" encoding="UTF-8"?>',
|
'<?xml version="1.0" encoding="UTF-8"?>',
|
||||||
|
|
|
||||||
|
|
@ -633,8 +633,10 @@
|
||||||
<div id="bambu-output" class="f-col">
|
<div id="bambu-output" class="f-col">
|
||||||
<div class="header"><label>send to bambu</label></div>
|
<div class="header"><label>send to bambu</label></div>
|
||||||
<div class="f-row box gap4 a-center">
|
<div class="f-row box gap4 a-center">
|
||||||
<label class="grow0">printer</label>
|
<label class="grow0 pad3">printer</label>
|
||||||
<select id="print-bambu-device"></select>
|
<select id="print-bambu-device"></select>
|
||||||
|
<label class="grow0 pad3">spool</label>
|
||||||
|
<select id="print-bambu-spool"></select>
|
||||||
<button id="print-bambu-1" class="grow" disabled>send</button>
|
<button id="print-bambu-1" class="grow" disabled>send</button>
|
||||||
<button id="print-bambu-2" class="grow" disabled>send + print</button>
|
<button id="print-bambu-2" class="grow" disabled>send + print</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue