2025-01-25 18:03:56 -05:00
|
|
|
self.kiri.load(api => {
|
|
|
|
|
|
|
|
|
|
if (api.electron || api.const.LOCAL) {
|
|
|
|
|
console.log('BAMBU MODULE RUNNING');
|
|
|
|
|
} else {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const { kiri, moto } = self;
|
2025-02-02 14:07:59 -05:00
|
|
|
const { ui } = kiri;
|
2025-01-26 22:46:44 -05:00
|
|
|
const h = moto.webui;
|
2025-01-25 18:03:56 -05:00
|
|
|
const defams = ";; DEFINE BAMBU-AMS ";
|
2025-02-02 14:07:59 -05:00
|
|
|
const readonly = true;
|
2025-01-25 18:03:56 -05:00
|
|
|
|
|
|
|
|
let init = false;
|
2025-01-28 12:45:35 -05:00
|
|
|
let status = {};
|
2025-02-02 16:10:05 -05:00
|
|
|
let bound, device, printers, select, selected, conn_alert;
|
2025-02-01 23:10:20 -05:00
|
|
|
let btn_del, in_host, in_code, in_serial, filelist;
|
2025-01-28 00:44:13 -05:00
|
|
|
let host, password, serial, amsmap, socket = {
|
|
|
|
|
open: false,
|
|
|
|
|
q: [],
|
|
|
|
|
start() {
|
|
|
|
|
if (socket.ws) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
let ws = socket.ws = new WebSocket("/bambu");
|
|
|
|
|
ws.onopen = () => {
|
|
|
|
|
socket.open = true;
|
|
|
|
|
socket.drain();
|
|
|
|
|
};
|
|
|
|
|
ws.onclose = () => {
|
|
|
|
|
socket.open = false;
|
2025-01-29 14:11:50 -05:00
|
|
|
socket.ws = undefined;
|
2025-01-28 00:44:13 -05:00
|
|
|
};
|
|
|
|
|
ws.onmessage = msg => {
|
2025-01-28 12:45:35 -05:00
|
|
|
let data = JSON.parse(msg.data);
|
2025-02-01 23:10:20 -05:00
|
|
|
let { serial, message, files, deleted, error } = data;
|
2025-01-28 12:45:35 -05:00
|
|
|
if (error) {
|
|
|
|
|
console.log({ serial, error });
|
2025-02-01 18:45:33 -05:00
|
|
|
api.alerts.show(`Bambu Error: ${error}`, 3);
|
|
|
|
|
// printer_status(`error: ${error}`);
|
2025-02-01 23:10:20 -05:00
|
|
|
} else if (deleted) {
|
|
|
|
|
console.log('file deleted', deleted);
|
|
|
|
|
file_list();
|
2025-01-28 12:45:35 -05:00
|
|
|
} else if (serial) {
|
|
|
|
|
let rec = status[serial] = deepMerge(status[serial] || {}, message);
|
2025-02-01 23:10:20 -05:00
|
|
|
if (files) {
|
|
|
|
|
rec.files = files;
|
|
|
|
|
}
|
2025-01-28 12:45:35 -05:00
|
|
|
if (selected?.rec.serial === serial) {
|
2025-02-01 23:10:20 -05:00
|
|
|
selected.status = rec;
|
2025-01-28 12:45:35 -05:00
|
|
|
printer_render(rec);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
console.log('ignored', serial, data);
|
|
|
|
|
}
|
2025-01-28 00:44:13 -05:00
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
stop() {
|
|
|
|
|
if (socket.ws) {
|
|
|
|
|
socket.ws.close();
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
drain() {
|
|
|
|
|
while (socket.open && socket.q.length) {
|
|
|
|
|
socket.ws.send(JSON.stringify(socket.q.shift()));
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
send(msg) {
|
|
|
|
|
socket.start();
|
|
|
|
|
socket.q.push(msg);
|
|
|
|
|
socket.drain();
|
|
|
|
|
}
|
|
|
|
|
};
|
2025-01-25 18:03:56 -05:00
|
|
|
|
2025-01-28 12:45:35 -05:00
|
|
|
function deepMerge(target, source) {
|
2025-01-29 00:35:56 -05:00
|
|
|
// console.log({ target, source });
|
|
|
|
|
if (!source) {
|
|
|
|
|
return target;
|
|
|
|
|
}
|
2025-01-28 12:45:35 -05:00
|
|
|
const result = structuredClone(target);
|
|
|
|
|
Object.keys(source).forEach((key) => {
|
|
|
|
|
if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {
|
|
|
|
|
result[key] = deepMerge(result[key] || {}, source[key]);
|
|
|
|
|
} else {
|
|
|
|
|
result[key] = source[key];
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
return result;
|
2025-01-28 12:56:23 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function deepSortObject(obj) {
|
|
|
|
|
if (Array.isArray(obj)) {
|
|
|
|
|
obj = obj.map(v => deepSortObject(v));
|
|
|
|
|
} else if (obj && typeof obj === "object" && !Array.isArray(obj)) {
|
|
|
|
|
return Object.keys(obj)
|
|
|
|
|
.sort()
|
|
|
|
|
.reduce((sorted, key) => {
|
|
|
|
|
sorted[key] = deepSortObject(obj[key]);
|
|
|
|
|
return sorted;
|
|
|
|
|
}, {});
|
|
|
|
|
}
|
|
|
|
|
return obj;
|
|
|
|
|
}
|
2025-01-28 12:45:35 -05:00
|
|
|
|
2025-01-26 22:46:44 -05:00
|
|
|
function printer_add() {
|
2025-02-02 16:10:05 -05:00
|
|
|
ui.prompt('printer name', "new printer").then(name => printer_add_named(name));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function printer_add_named(name) {
|
2025-01-27 22:48:44 -05:00
|
|
|
printers[name] = printers[name] || {
|
|
|
|
|
host:'', code:'', serial:''
|
|
|
|
|
};
|
|
|
|
|
render_list();
|
2025-01-28 22:55:59 -05:00
|
|
|
select.value = name;
|
|
|
|
|
printer_select(name);
|
2025-01-26 22:46:44 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function printer_del() {
|
2025-01-29 14:11:50 -05:00
|
|
|
if (!selected?.name) {
|
2025-01-27 22:48:44 -05:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
delete printers[selected.name];
|
|
|
|
|
render_list();
|
2025-01-28 22:55:59 -05:00
|
|
|
select.value = '';
|
|
|
|
|
printer_select();
|
2025-01-27 22:48:44 -05:00
|
|
|
}
|
|
|
|
|
|
2025-01-28 09:54:00 -05:00
|
|
|
function printer_update() {
|
|
|
|
|
Object.assign(selected.rec, {
|
|
|
|
|
host: in_host.value,
|
|
|
|
|
code: in_code.value,
|
|
|
|
|
serial: in_serial.value,
|
|
|
|
|
modified: true
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-28 22:55:59 -05:00
|
|
|
function printer_select(name = '') {
|
2025-01-27 22:48:44 -05:00
|
|
|
btn_del.disabled = false;
|
|
|
|
|
let rec = printers[name] || {};
|
|
|
|
|
selected = { name, rec };
|
|
|
|
|
in_host.value = rec.host || '';
|
|
|
|
|
in_code.value = rec.code || '';
|
|
|
|
|
in_serial.value = rec.serial || '';
|
2025-01-28 09:54:00 -05:00
|
|
|
in_host.onkeypress = in_host.onblur = printer_update;
|
|
|
|
|
in_code.onkeypress = in_code.onblur = printer_update;
|
|
|
|
|
in_serial.onkeypress = in_serial.onblur = printer_update;
|
2025-01-28 00:44:13 -05:00
|
|
|
monitor_start(rec);
|
2025-01-28 22:55:59 -05:00
|
|
|
printer_render();
|
2025-02-01 23:10:20 -05:00
|
|
|
file_list();
|
2025-01-28 16:37:44 -05:00
|
|
|
$('bbl_name').innerText = name;
|
2025-01-27 22:48:44 -05:00
|
|
|
}
|
|
|
|
|
|
2025-01-28 22:55:59 -05:00
|
|
|
function printer_render(rec = {}) {
|
2025-01-29 00:35:56 -05:00
|
|
|
let { info, print, files } = rec;
|
2025-01-28 16:37:44 -05:00
|
|
|
let {
|
2025-02-02 14:07:59 -05:00
|
|
|
ams,
|
2025-01-28 16:37:44 -05:00
|
|
|
ams_status,
|
2025-01-28 21:13:44 -05:00
|
|
|
bed_target_temper,
|
2025-01-28 16:37:44 -05:00
|
|
|
bed_temper,
|
|
|
|
|
big_fan1_speed,
|
|
|
|
|
big_fan2_speed,
|
|
|
|
|
chamber_temper,
|
|
|
|
|
cooling_fan_speed,
|
2025-02-02 14:07:59 -05:00
|
|
|
fan_gear,
|
2025-01-28 16:37:44 -05:00
|
|
|
gcode_file,
|
2025-02-02 00:09:19 -05:00
|
|
|
gcode_state, // PREPARE, PAUSE, RUNNING, FAILED
|
2025-01-28 16:37:44 -05:00
|
|
|
heatbreak_fan_speed,
|
2025-02-02 14:07:59 -05:00
|
|
|
home_flag,
|
2025-01-28 16:37:44 -05:00
|
|
|
layer_num,
|
2025-02-02 14:07:59 -05:00
|
|
|
lights_report,
|
2025-01-28 16:37:44 -05:00
|
|
|
mc_percent,
|
|
|
|
|
mc_remaining_time,
|
|
|
|
|
nozzle_diameter,
|
|
|
|
|
nozzle_target_temper,
|
|
|
|
|
nozzle_temper,
|
|
|
|
|
print_error,
|
|
|
|
|
print_type,
|
|
|
|
|
sdcard,
|
|
|
|
|
total_layer_num,
|
|
|
|
|
upload
|
|
|
|
|
} = print || {};
|
2025-02-01 23:10:20 -05:00
|
|
|
let state = (gcode_state || 'unknown').toLowerCase();
|
2025-01-28 22:55:59 -05:00
|
|
|
$('bbl_noz').value = nozzle_diameter || '';
|
2025-02-01 01:36:56 -05:00
|
|
|
$('bbl_noz_temp').value = nozzle_temper?.toFixed(1) ?? '';
|
|
|
|
|
$('bbl_noz_target').value = nozzle_target_temper?.toFixed(1) ?? '';
|
2025-02-02 14:07:59 -05:00
|
|
|
$('bbl_noz_on').checked = nozzle_target_temper > 0;
|
2025-02-01 01:36:56 -05:00
|
|
|
$('bbl_bed_temp').value = bed_temper?.toFixed(1) ?? '';
|
|
|
|
|
$('bbl_bed_target').value = bed_target_temper?.toFixed(1) ?? '';
|
2025-02-02 14:07:59 -05:00
|
|
|
$('bbl_bed_on').checked = bed_target_temper > 0;
|
2025-02-01 23:10:20 -05:00
|
|
|
$('bbl_pause').disabled = (gcode_state !== 'RUNNING');
|
2025-02-02 01:12:58 -05:00
|
|
|
$('bbl_resume').disabled = (gcode_state !== 'PAUSE' || gcode_state === 'FAILED');
|
2025-02-02 00:09:19 -05:00
|
|
|
$('bbl_fan_part').value = cooling_fan_speed || 0;
|
2025-02-02 14:07:59 -05:00
|
|
|
$('bbl_fan_part_on').checked = cooling_fan_speed > 0 ? true : false;
|
2025-02-02 00:09:19 -05:00
|
|
|
$('bbl_fan_1').value = big_fan1_speed || 0;
|
2025-02-02 14:07:59 -05:00
|
|
|
$('bbl_fan_1_on').checked = big_fan1_speed > 0 ? true : false;
|
2025-02-02 00:09:19 -05:00
|
|
|
$('bbl_fan_2').value = big_fan2_speed || 0;
|
2025-02-02 14:07:59 -05:00
|
|
|
$('bbl_fan_2_on').checked = big_fan2_speed > 0 ? true : false;
|
2025-02-02 00:09:19 -05:00
|
|
|
$('bbl_fan_heatbreak').value = heatbreak_fan_speed || 0;
|
|
|
|
|
$('bbl_file_active').value = gcode_file || '';
|
2025-02-01 23:10:20 -05:00
|
|
|
if (files && filelist.selectedIndex === -1) {
|
|
|
|
|
h.bind(filelist, files.map(file => {
|
2025-02-01 18:45:33 -05:00
|
|
|
let name = file.name
|
|
|
|
|
.toLowerCase()
|
|
|
|
|
.replace('.gcode','')
|
|
|
|
|
.replace('.3mf','');
|
2025-01-29 00:35:56 -05:00
|
|
|
return h.option({
|
2025-02-01 18:45:33 -05:00
|
|
|
_: name,
|
2025-02-01 23:10:20 -05:00
|
|
|
style: "max-width: 20em"
|
2025-01-29 00:35:56 -05:00
|
|
|
});
|
|
|
|
|
}));
|
2025-02-01 23:10:20 -05:00
|
|
|
filelist.selectedIndex = 0;
|
|
|
|
|
filelist.onchange();
|
2025-01-29 00:35:56 -05:00
|
|
|
}
|
2025-02-02 14:07:59 -05:00
|
|
|
(lights_report || []).forEach(rec => {
|
|
|
|
|
if (rec.node === 'chamber_light') {
|
|
|
|
|
$('bbl_chamber_light').checked = (rec.mode === 'on');
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
ui.setVisible($('bbl_ams'), ams?.version ? true : false);
|
|
|
|
|
$('bbl_ams_spool').checked = ((home_flag ?? 0) & 0x400) ? true : false;
|
|
|
|
|
$('bbl_step_recover').checked = ((home_flag ?? 0) & 0x10) ? true : false;
|
2025-02-01 23:10:20 -05:00
|
|
|
// provide only the print info from the serial recorld
|
2025-02-02 14:07:59 -05:00
|
|
|
$('bbl_rec').value = JSON.stringify(deepSortObject({
|
|
|
|
|
...rec.print
|
|
|
|
|
// info: rec.info,
|
|
|
|
|
// print: rec.print,
|
|
|
|
|
}), undefined, 2);
|
2025-02-01 01:36:56 -05:00
|
|
|
if (print_error) {
|
|
|
|
|
bbl_status.value = `print error ${print_error}`
|
2025-02-01 23:10:20 -05:00
|
|
|
} else if (mc_remaining_time && gcode_state !== 'FAILED') {
|
|
|
|
|
bbl_status.value = `layer ${layer_num} of ${total_layer_num} | ${mc_percent}% complete | ${mc_remaining_time} minutes left | ${state}`
|
2025-02-01 01:36:56 -05:00
|
|
|
} else {
|
2025-02-01 23:10:20 -05:00
|
|
|
bbl_status.value = `printer ${print_type || ""} | ${state}`;
|
2025-02-01 01:36:56 -05:00
|
|
|
}
|
2025-02-02 16:10:05 -05:00
|
|
|
if (gcode_state && conn_alert) {
|
|
|
|
|
api.alerts.hide(conn_alert);
|
|
|
|
|
}
|
2025-01-28 12:45:35 -05:00
|
|
|
}
|
|
|
|
|
|
2025-02-01 18:45:33 -05:00
|
|
|
function render_list(to) {
|
2025-01-28 22:55:59 -05:00
|
|
|
let list = Object.keys(printers).map(name => {
|
2025-02-01 23:10:20 -05:00
|
|
|
return selected?.name === name ?
|
|
|
|
|
h.option({ _: name, value: name, selected: true }) :
|
|
|
|
|
h.option({ _: name, value: name });
|
2025-01-28 22:55:59 -05:00
|
|
|
});
|
|
|
|
|
list = [
|
|
|
|
|
h.option({ _: '', value: '' }),
|
|
|
|
|
...list
|
|
|
|
|
]
|
2025-02-01 18:45:33 -05:00
|
|
|
h.bind(to || select, list);
|
2025-01-26 22:46:44 -05:00
|
|
|
}
|
|
|
|
|
|
2025-01-28 00:44:13 -05:00
|
|
|
function monitor_start(rec) {
|
2025-01-28 22:55:59 -05:00
|
|
|
let { host, code, serial } = rec;
|
|
|
|
|
if (!(host && code && serial)) {
|
|
|
|
|
// monitor_stop();
|
|
|
|
|
} else {
|
|
|
|
|
socket.send({ cmd: "monitor", ...rec });
|
|
|
|
|
}
|
2025-01-28 00:44:13 -05:00
|
|
|
}
|
|
|
|
|
|
2025-01-28 12:45:35 -05:00
|
|
|
function monitor_keepalive() {
|
|
|
|
|
// console.log({ keepalive: selected });
|
2025-02-01 01:36:56 -05:00
|
|
|
// if (monitoring()) {
|
|
|
|
|
// socket.send({ cmd: "keepalive", serial: selected.rec.serial });
|
|
|
|
|
// }
|
|
|
|
|
cmd_if("keepalive");
|
2025-01-28 12:45:35 -05:00
|
|
|
}
|
|
|
|
|
|
2025-01-28 00:44:13 -05:00
|
|
|
function monitor_stop() {
|
|
|
|
|
socket.stop();
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-01 01:36:56 -05:00
|
|
|
function monitoring() {
|
2025-02-02 16:10:05 -05:00
|
|
|
let active = selected?.rec?.serial ? true : false;
|
|
|
|
|
ui.setVisible($('bbl_connect'), !active && select.value !== '');
|
|
|
|
|
return active;
|
2025-02-01 01:36:56 -05:00
|
|
|
}
|
|
|
|
|
|
2025-02-02 14:07:59 -05:00
|
|
|
function cmd_if(cmd, obj = {}) {
|
2025-02-01 01:36:56 -05:00
|
|
|
if (monitoring()) {
|
2025-02-02 14:07:59 -05:00
|
|
|
socket.send({ ...obj, cmd, serial: selected.rec.serial });
|
2025-02-01 01:36:56 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-02 14:07:59 -05:00
|
|
|
function cmd_direct(obj = {}) {
|
|
|
|
|
cmd_if("direct", { direct: obj });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function cmd_gcode(code) {
|
|
|
|
|
cmd_direct({ print: {
|
|
|
|
|
command: "gcode_line",
|
|
|
|
|
param: `${code} \n`
|
|
|
|
|
} });
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-01 23:10:20 -05:00
|
|
|
function file_list() {
|
2025-01-29 00:35:56 -05:00
|
|
|
if (selected?.rec?.host) {
|
2025-02-01 23:10:20 -05:00
|
|
|
filelist.selectedIndex = -1;
|
|
|
|
|
$('bbl_file_size').value =
|
|
|
|
|
$('bbl_file_date').value = '';
|
|
|
|
|
$('bbl_file_delete').disabled =
|
|
|
|
|
$('bbl_file_print').disabled = true;
|
2025-01-29 00:35:56 -05:00
|
|
|
socket.send({ cmd: "files", ...selected.rec });
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-01 23:10:20 -05:00
|
|
|
function file_delete(path) {
|
|
|
|
|
if (selected?.rec?.host && path) {
|
|
|
|
|
let { host, code } = selected.rec
|
|
|
|
|
socket.send({ cmd: "file-delete", path, host, code });
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function file_print(path) {
|
|
|
|
|
if (selected?.rec?.host && path) {
|
|
|
|
|
let { host, code, serial } = selected.rec;
|
|
|
|
|
socket.send({ cmd: "file-print", path, host, code, serial, amsmap });
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-25 18:03:56 -05:00
|
|
|
api.event.on("init-done", function() {
|
2025-02-02 16:10:05 -05:00
|
|
|
console.log({ init_done: init });
|
2025-01-26 22:46:44 -05:00
|
|
|
if (init) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2025-01-25 18:03:56 -05:00
|
|
|
init = true;
|
2025-01-26 22:46:44 -05:00
|
|
|
bound = h.bind($('device-save'), h.button({
|
|
|
|
|
_: 'Manage', id: "bblman", onclick() {
|
|
|
|
|
api.modal.show('bambu');
|
|
|
|
|
}
|
|
|
|
|
}), { before: true });
|
|
|
|
|
let modal = h.bind($('mod-help'), h.div({
|
|
|
|
|
id: "mod-bambu",
|
2025-01-28 21:13:44 -05:00
|
|
|
class: "mdialog f-col gap4"
|
2025-01-26 22:46:44 -05:00
|
|
|
}, [
|
2025-01-28 16:37:44 -05:00
|
|
|
h.div({ class: "f-row a-center gap4" }, [
|
|
|
|
|
h.label({ class: "set-header dev-sel" }, [ h.a('bambu manager') ]),
|
|
|
|
|
h.select({ id: "bbl_sel", class: "dev-list" }, []),
|
2025-02-02 16:10:05 -05:00
|
|
|
h.button({ _: "connect", class: "hide", id: "bbl_connect", onclick() {
|
|
|
|
|
conn_alert = api.alerts.show(`connecting to ${select.value}`);
|
|
|
|
|
printer_select(select.value);
|
|
|
|
|
} }),
|
2025-01-28 16:37:44 -05:00
|
|
|
h.div({ class: "grow gap3 j-end" }, [
|
2025-01-29 14:11:50 -05:00
|
|
|
h.button({
|
|
|
|
|
id: "bbl_hide",
|
|
|
|
|
_: '<i class="fa-solid fa-eye"></i>',
|
|
|
|
|
class: "a-center",
|
|
|
|
|
onclick(ev) {
|
2025-01-28 22:55:59 -05:00
|
|
|
if (ev.target.hide === true) {
|
|
|
|
|
ev.target.hide = false;
|
|
|
|
|
$('bbl_code').type = 'text';
|
|
|
|
|
$('bbl_serial').type = 'text';
|
|
|
|
|
$('bbl_hide').innerHTML = '<i class="fa-solid fa-eye"></i>';
|
|
|
|
|
} else {
|
|
|
|
|
ev.target.hide = true;
|
|
|
|
|
$('bbl_code').type = 'password';
|
|
|
|
|
$('bbl_serial').type = 'password';
|
|
|
|
|
$('bbl_hide').innerHTML = '<i class="fa-solid fa-eye-slash"></i>';
|
|
|
|
|
}
|
|
|
|
|
}}),
|
2025-01-28 16:37:44 -05:00
|
|
|
h.button({
|
|
|
|
|
_: 'new',
|
|
|
|
|
title: "add printer",
|
|
|
|
|
class: "grid",
|
|
|
|
|
onclick: printer_add
|
|
|
|
|
}),
|
|
|
|
|
h.button({
|
|
|
|
|
_: 'rename',
|
|
|
|
|
title: "rename printer",
|
|
|
|
|
class: "grid",
|
|
|
|
|
onclick: printer_add
|
|
|
|
|
}),
|
|
|
|
|
h.button({
|
|
|
|
|
_: 'delete',
|
|
|
|
|
id: 'bbl_pdel',
|
|
|
|
|
title: "remove printer",
|
|
|
|
|
class: "grid",
|
|
|
|
|
onclick: printer_del
|
|
|
|
|
})
|
|
|
|
|
])
|
|
|
|
|
]),
|
|
|
|
|
h.div({ class: "set-sep "}),
|
2025-01-28 22:55:59 -05:00
|
|
|
h.div({ class: "frow gap4" }, [
|
2025-01-28 21:13:44 -05:00
|
|
|
h.div({ class: "f-col gap3" }, [
|
|
|
|
|
h.div({ class: "t-body t-inset f-col" }, [
|
2025-01-28 16:37:44 -05:00
|
|
|
h.label({ class: "set-header dev-sel" }, [
|
|
|
|
|
h.a({ _: 'printer', id: "bbl_name" })
|
|
|
|
|
]),
|
2025-01-28 21:13:44 -05:00
|
|
|
h.div({ class: "var-row" }, [
|
|
|
|
|
h.label('host'),
|
|
|
|
|
h.input({ id: "bbl_host", size: 12 }),
|
|
|
|
|
]),
|
|
|
|
|
h.div({ class: "var-row" }, [
|
|
|
|
|
h.label('code'),
|
|
|
|
|
h.input({ id: "bbl_code", size: 12 }),
|
|
|
|
|
]),
|
|
|
|
|
h.div({ class: "var-row" }, [
|
|
|
|
|
h.label('serial'),
|
|
|
|
|
h.input({ id: "bbl_serial", size: 17, class: "font-smol" }),
|
|
|
|
|
])
|
2025-01-27 22:48:44 -05:00
|
|
|
]),
|
2025-01-28 21:13:44 -05:00
|
|
|
h.div({ class: "t-body t-inset f-col" }, [
|
|
|
|
|
h.label({ class: "set-header dev-sel" }, [
|
|
|
|
|
h.a('nozzle')
|
|
|
|
|
]),
|
|
|
|
|
h.div({ class: "var-row" }, [
|
|
|
|
|
h.label('diameter'),
|
2025-02-02 14:07:59 -05:00
|
|
|
h.input({ id: "bbl_noz", size: 5, readonly })
|
2025-01-28 21:13:44 -05:00
|
|
|
]),
|
|
|
|
|
h.div({ class: "var-row" }, [
|
2025-01-28 16:37:44 -05:00
|
|
|
h.label('temp'),
|
2025-02-02 14:07:59 -05:00
|
|
|
h.input({ id: "bbl_noz_temp", size: 5, readonly })
|
2025-01-28 21:13:44 -05:00
|
|
|
]),
|
2025-02-02 14:07:59 -05:00
|
|
|
h.div({ class: "var-row", ondblclick() {
|
2025-02-02 16:10:05 -05:00
|
|
|
ui.prompt('new nozzle temp', $('bbl_noz_target').value).then(value => {
|
|
|
|
|
cmd_gcode(`M104 S${value}`);
|
|
|
|
|
api.alerts.show(`set nozzle temp ${value}`);
|
|
|
|
|
})
|
2025-02-02 14:07:59 -05:00
|
|
|
} }, [
|
2025-01-28 16:37:44 -05:00
|
|
|
h.label('target'),
|
2025-02-02 14:07:59 -05:00
|
|
|
h.input({ id: "bbl_noz_on", type: "checkbox", onclick() {
|
|
|
|
|
let value = $('bbl_noz_on').checked ? '220' : '0';
|
|
|
|
|
cmd_gcode(`M104 S${value}`)
|
2025-02-02 16:10:05 -05:00
|
|
|
api.alerts.show(`set nozzle temp ${value}`);
|
2025-02-02 14:07:59 -05:00
|
|
|
} }),
|
|
|
|
|
h.input({ id: "bbl_noz_target", size: 5, readonly })
|
2025-01-28 21:13:44 -05:00
|
|
|
])
|
|
|
|
|
]),
|
|
|
|
|
h.div({ class: "t-body t-inset f-col" }, [
|
|
|
|
|
h.label({ class: "set-header dev-sel" }, [
|
|
|
|
|
h.a('bed')
|
2025-01-28 16:37:44 -05:00
|
|
|
]),
|
2025-01-28 21:13:44 -05:00
|
|
|
h.div({ class: "var-row" }, [
|
|
|
|
|
h.label('temp'),
|
2025-02-02 14:07:59 -05:00
|
|
|
h.input({ id: "bbl_bed_temp", size: 5, readonly })
|
2025-01-28 21:13:44 -05:00
|
|
|
]),
|
2025-02-02 14:07:59 -05:00
|
|
|
h.div({ class: "var-row", ondblclick() {
|
2025-02-02 16:10:05 -05:00
|
|
|
ui.prompt('new bed temp', $('bbl_bed_target').value).then(value => {
|
2025-02-02 14:07:59 -05:00
|
|
|
cmd_gcode(`M140 S${value}`)
|
2025-02-02 16:10:05 -05:00
|
|
|
api.alerts.show(`set bed temp ${value}`);
|
|
|
|
|
})
|
2025-02-02 14:07:59 -05:00
|
|
|
} }, [
|
2025-01-28 21:13:44 -05:00
|
|
|
h.label('target'),
|
2025-02-02 14:07:59 -05:00
|
|
|
h.input({ id: "bbl_bed_on", type: "checkbox", onclick() {
|
|
|
|
|
let value = $('bbl_bed_on').checked ? '60' : '0';
|
|
|
|
|
cmd_gcode(`M140 S${value}`);
|
2025-02-02 16:10:05 -05:00
|
|
|
api.alerts.show(`set bed temp ${value}`);
|
2025-02-02 14:07:59 -05:00
|
|
|
} }),
|
|
|
|
|
h.input({ id: "bbl_bed_target", size: 5, readonly })
|
2025-01-28 21:13:44 -05:00
|
|
|
])
|
2025-02-02 00:09:19 -05:00
|
|
|
]),
|
|
|
|
|
h.div({ class: "t-body t-inset f-col" }, [
|
|
|
|
|
h.label({ class: "set-header dev-sel" }, [
|
2025-02-02 14:07:59 -05:00
|
|
|
h.a('chamber')
|
2025-02-02 00:09:19 -05:00
|
|
|
]),
|
2025-02-02 14:07:59 -05:00
|
|
|
h.div({ class: "var-row", ondblclick() {
|
2025-02-02 16:10:05 -05:00
|
|
|
ui.prompt('new part fan value', $('bbl_fan_part').value).then(value => {
|
|
|
|
|
cmd_gcode(`M106 P1 S${value}`);
|
|
|
|
|
api.alerts.show(`set part fan ${value}`);
|
|
|
|
|
})
|
2025-02-02 14:07:59 -05:00
|
|
|
} }, [
|
|
|
|
|
h.label('part fan'),
|
|
|
|
|
h.input({ id: "bbl_fan_part_on", type: "checkbox", onclick() {
|
|
|
|
|
let value = $('bbl_fan_part_on').checked ? '255' : '0';
|
|
|
|
|
cmd_gcode(`M106 P1 S${value}`)
|
2025-02-02 16:10:05 -05:00
|
|
|
api.alerts.show(`set part fan ${value}`);
|
2025-02-02 14:07:59 -05:00
|
|
|
} }),
|
|
|
|
|
h.input({ id: "bbl_fan_part", size: 5, readonly })
|
2025-02-02 00:09:19 -05:00
|
|
|
]),
|
2025-02-02 14:07:59 -05:00
|
|
|
h.div({ class: "var-row", ondblclick() {
|
2025-02-02 16:10:05 -05:00
|
|
|
ui.prompt('new aux fan value', $('bbl_fan_1').value).then(value => {
|
|
|
|
|
cmd_gcode(`M106 P2 S${value}`);
|
|
|
|
|
api.alerts.show(`set aux fan ${value}`);
|
|
|
|
|
})
|
2025-02-02 14:07:59 -05:00
|
|
|
} }, [
|
|
|
|
|
h.label('aux fan'),
|
|
|
|
|
h.input({ id: "bbl_fan_1_on", type: "checkbox", onclick() {
|
|
|
|
|
let value = $('bbl_fan_1_on').checked ? '255' : '0';
|
|
|
|
|
cmd_gcode(`M106 P2 S${value}`)
|
2025-02-02 16:10:05 -05:00
|
|
|
api.alerts.show(`set aux fan ${value}`);
|
2025-02-02 14:07:59 -05:00
|
|
|
} }),
|
|
|
|
|
h.input({ id: "bbl_fan_1", size: 5, readonly })
|
|
|
|
|
]),
|
|
|
|
|
h.div({ class: "var-row", ondblclick() {
|
2025-02-02 16:10:05 -05:00
|
|
|
ui.prompt('new chamber fan value', $('bbl_fan_2').value).then(value => {
|
|
|
|
|
cmd_gcode(`M106 P3 S${value}`);
|
|
|
|
|
api.alerts.show(`set chamber fan ${value}`);
|
|
|
|
|
})
|
2025-02-02 14:07:59 -05:00
|
|
|
} }, [
|
|
|
|
|
h.label('chamber fan'),
|
|
|
|
|
h.input({ id: "bbl_fan_2_on", type: "checkbox", onclick() {
|
|
|
|
|
let value = $('bbl_fan_2_on').checked ? '255' : '0';
|
|
|
|
|
cmd_gcode(`M106 P3 S${value}`)
|
2025-02-02 16:10:05 -05:00
|
|
|
api.alerts.show(`set chamber fan ${value}`);
|
2025-02-02 14:07:59 -05:00
|
|
|
} }),
|
|
|
|
|
h.input({ id: "bbl_fan_2", size: 5, readonly })
|
2025-02-02 00:09:19 -05:00
|
|
|
]),
|
|
|
|
|
h.div({ class: "var-row" }, [
|
2025-02-02 14:07:59 -05:00
|
|
|
h.label('heatbreak fan'),
|
|
|
|
|
h.input({ id: "bbl_fan_heatbreak", size: 5, readonly })
|
2025-02-02 00:09:19 -05:00
|
|
|
]),
|
|
|
|
|
h.div({ class: "var-row" }, [
|
2025-02-02 14:07:59 -05:00
|
|
|
h.label('light'),
|
|
|
|
|
h.input({ id: "bbl_chamber_light", type: "checkbox", onclick() {
|
|
|
|
|
cmd_direct({
|
|
|
|
|
system: {
|
|
|
|
|
command: "ledctrl",
|
|
|
|
|
led_node: "chamber_light",
|
|
|
|
|
led_mode: $('bbl_chamber_light').checked ? "on" : "off"
|
|
|
|
|
}
|
|
|
|
|
})
|
2025-02-02 16:10:05 -05:00
|
|
|
api.alerts.show(`set chamber light`);
|
2025-02-02 14:07:59 -05:00
|
|
|
} })
|
|
|
|
|
]),
|
2025-01-28 21:13:44 -05:00
|
|
|
])
|
|
|
|
|
]),
|
2025-01-28 22:55:59 -05:00
|
|
|
h.div({ class: "f-col gap4 grow" }, [
|
|
|
|
|
h.textarea({
|
|
|
|
|
id: "bbl_rec",
|
|
|
|
|
style: "width: 100%; height: 100%; resize: none; box-sizing: border-box",
|
|
|
|
|
wrap: "off",
|
|
|
|
|
spellcheck: "false",
|
|
|
|
|
rows: 15, cols: 65
|
|
|
|
|
})
|
2025-01-28 16:37:44 -05:00
|
|
|
]),
|
2025-02-01 23:10:20 -05:00
|
|
|
h.div({ class: "f-col gap3" }, [
|
2025-02-02 14:07:59 -05:00
|
|
|
h.div({ id: "bbl_ams", class: "hide t-body t-inset f-col gap3 pad4" }, [
|
|
|
|
|
h.label({ class: "set-header dev-sel" }, [
|
|
|
|
|
h.a('ams')
|
|
|
|
|
]),
|
|
|
|
|
// { print: { auto_recovery: true, command: 'print_option', option: 1, reason: 'success', result: 'success', sequence_id: '20005' } }
|
|
|
|
|
h.div({ class: "var-row" }, [
|
|
|
|
|
// home_flag bit 11 (0x400)
|
|
|
|
|
h.label('auto spool advance'),
|
|
|
|
|
h.input({ id: "bbl_ams_spool", type: "checkbox", onclick() {
|
|
|
|
|
cmd_direct({
|
|
|
|
|
print: {
|
|
|
|
|
auto_switch_filament: $('bbl_ams_spool').checked,
|
|
|
|
|
command: 'print_option',
|
|
|
|
|
sequence_id: '123',
|
|
|
|
|
option: $('bbl_ams_spool').checked ? 1 : 0
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
} })
|
|
|
|
|
]),
|
|
|
|
|
]),
|
|
|
|
|
h.div({ class: "t-body t-inset f-col gap3 pad4 grow" }, [
|
|
|
|
|
h.label({ class: "set-header dev-sel" }, [
|
|
|
|
|
h.a('print options')
|
|
|
|
|
]),
|
|
|
|
|
h.div({ class: "var-row" }, [
|
|
|
|
|
// home_flag bit 5 (0x10)
|
|
|
|
|
h.label('auto step recovery'),
|
|
|
|
|
h.input({ id: "bbl_step_recover", type: "checkbox", onclick() {
|
|
|
|
|
cmd_direct({
|
|
|
|
|
print: {
|
|
|
|
|
auto_recovery: $('bbl_step_recover').checked,
|
|
|
|
|
command: 'print_option',
|
|
|
|
|
sequence_id: '124',
|
|
|
|
|
option: $('bbl_step_recover').checked ? 1 : 0
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
} })
|
|
|
|
|
]),
|
|
|
|
|
]),
|
|
|
|
|
// ]),
|
|
|
|
|
// h.div({ class: "f-col gap3" }, [
|
2025-02-01 23:10:20 -05:00
|
|
|
h.div({ class: "t-body t-inset f-col gap3 pad4 grow" }, [
|
|
|
|
|
h.div({ class: "set-header", onclick() {
|
|
|
|
|
file_list();
|
|
|
|
|
} }, h.a({ class: "flex f-row grow" }, [
|
|
|
|
|
h.label('file'),
|
|
|
|
|
h.span({ class: "fat5 grow" }),
|
|
|
|
|
h.i({ class: "fa-solid fa-rotate" })
|
|
|
|
|
])),
|
|
|
|
|
h.select({ id: "bbl_files" }, []),
|
|
|
|
|
h.div({ class: "var-row" }, [
|
|
|
|
|
h.label('size'),
|
2025-02-02 14:07:59 -05:00
|
|
|
h.input({ id: "bbl_file_size", size: 12, readonly })
|
2025-02-01 23:10:20 -05:00
|
|
|
]),
|
|
|
|
|
h.div({ class: "var-row" }, [
|
|
|
|
|
h.label('date'),
|
2025-02-02 14:07:59 -05:00
|
|
|
h.input({ id: "bbl_file_date", size: 12, readonly })
|
2025-02-01 23:10:20 -05:00
|
|
|
]),
|
|
|
|
|
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({
|
|
|
|
|
_: 'print',
|
|
|
|
|
id: "bbl_file_print",
|
|
|
|
|
class: "f-col a-center t-center",
|
|
|
|
|
disabled: true,
|
|
|
|
|
onclick() {
|
|
|
|
|
console.log({ printing: selected.file.path });
|
|
|
|
|
file_print(selected.file.path);
|
|
|
|
|
}}),
|
2025-02-02 00:09:19 -05:00
|
|
|
]),
|
|
|
|
|
h.div({ class: "t-body t-inset f-col gap3 pad4" }, [
|
|
|
|
|
h.label({ class: "set-header dev-sel" }, [
|
|
|
|
|
h.a('active file')
|
|
|
|
|
]),
|
|
|
|
|
h.div({ class: "var-row" }, [
|
2025-02-02 14:07:59 -05:00
|
|
|
h.input({ id: "bbl_file_active", class: "t-left", readonly })
|
2025-02-02 00:09:19 -05:00
|
|
|
]),
|
2025-02-01 23:10:20 -05:00
|
|
|
])
|
2025-01-26 22:46:44 -05:00
|
|
|
])
|
2025-01-28 21:13:44 -05:00
|
|
|
]),
|
|
|
|
|
h.div({ class: "set-sep "}),
|
|
|
|
|
h.div({ class: "gap4" }, [
|
|
|
|
|
h.label({ class: "set-header dev-sel" }, [ h.a('status') ]),
|
2025-01-29 14:11:50 -05:00
|
|
|
h.input({ id: "bbl_status", class: "t-left mono grow" }),
|
2025-02-01 23:10:20 -05:00
|
|
|
h.button({ _: "pause", id: "bbl_pause", class: "a-center", onclick() { cmd_if("pause") } }),
|
|
|
|
|
h.button({ _: "resume", id: "bbl_resume", class: "a-center", onclick() { cmd_if("resume") } }),
|
2025-02-02 16:10:05 -05:00
|
|
|
h.button({ _: "stop", class: "a-center", onclick() { cmd_if("cancel") } }),
|
2025-01-26 22:46:44 -05:00
|
|
|
])
|
|
|
|
|
]), { before: true });
|
|
|
|
|
select = modal.bbl_sel;
|
2025-02-01 23:10:20 -05:00
|
|
|
filelist = modal.bbl_files;
|
2025-01-27 22:48:44 -05:00
|
|
|
btn_del = modal.bbl_pdel;
|
|
|
|
|
in_host = modal.bbl_host;
|
|
|
|
|
in_code = modal.bbl_code;
|
|
|
|
|
in_serial = modal.bbl_serial;
|
2025-01-26 22:46:44 -05:00
|
|
|
api.ui.modals['bambu'] = modal['mod-bambu'];
|
2025-01-27 22:48:44 -05:00
|
|
|
btn_del.disabled = true;
|
2025-01-28 22:55:59 -05:00
|
|
|
select.onchange = (ev => printer_select(select.value));
|
2025-02-01 23:10:20 -05:00
|
|
|
filelist.onchange = (ev => {
|
|
|
|
|
let file = selected.file = selected.status.files[filelist.selectedIndex];
|
|
|
|
|
$('bbl_file_size').value = file.size;
|
|
|
|
|
$('bbl_file_date').value = file.date;
|
|
|
|
|
$('bbl_file_delete').disabled =
|
|
|
|
|
$('bbl_file_print').disabled = false;
|
|
|
|
|
});
|
2025-01-26 22:46:44 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
api.event.on("modal.show", which => {
|
|
|
|
|
if (which !== 'bambu' || !device) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2025-01-27 22:48:44 -05:00
|
|
|
render_list();
|
2025-02-01 23:10:20 -05:00
|
|
|
get_ams_map(api.conf.get());
|
2025-01-26 20:13:31 -05:00
|
|
|
});
|
|
|
|
|
|
2025-01-28 09:54:00 -05:00
|
|
|
api.event.on("modal.hide", which => {
|
|
|
|
|
if (selected?.rec.modified) {
|
|
|
|
|
api.conf.save();
|
|
|
|
|
}
|
2025-01-29 14:11:50 -05:00
|
|
|
selected = undefined;
|
|
|
|
|
status = {};
|
2025-01-28 09:54:00 -05:00
|
|
|
});
|
|
|
|
|
|
2025-01-26 20:13:31 -05:00
|
|
|
api.event.on("device.selected", devsel => {
|
|
|
|
|
if (!bound) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2025-01-26 22:46:44 -05:00
|
|
|
if (devsel.extras?.bbl) {
|
|
|
|
|
device = devsel;
|
2025-01-27 22:48:44 -05:00
|
|
|
printers = devsel.extras.bbl;
|
2025-01-26 20:13:31 -05:00
|
|
|
bound.bblman.classList.remove('hide');
|
|
|
|
|
} else {
|
2025-01-26 22:46:44 -05:00
|
|
|
device = undefined;
|
2025-01-27 22:48:44 -05:00
|
|
|
printers = undefined;
|
2025-01-26 20:13:31 -05:00
|
|
|
bound.bblman.classList.add('hide');
|
|
|
|
|
}
|
2025-01-25 18:03:56 -05:00
|
|
|
});
|
|
|
|
|
|
2025-02-01 23:10:20 -05:00
|
|
|
function get_ams_map(settings) {
|
|
|
|
|
const ams = settings.device?.gcodePre.filter(line => line.indexOf(defams) === 0)[0];
|
|
|
|
|
if (ams) {
|
|
|
|
|
try {
|
|
|
|
|
amsmap = ams.substring(defams.length).trim().replaceAll(' ','');
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.log({ invalid_ams_map: ams });
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-01 18:45:33 -05:00
|
|
|
function prep_export(gen3mf, gcode, info, settings) {
|
|
|
|
|
if (!settings.device.extras?.bbl) {
|
|
|
|
|
$('bambu-output').style.display = 'none';
|
|
|
|
|
return;
|
2025-01-25 18:03:56 -05:00
|
|
|
}
|
2025-02-01 18:45:33 -05:00
|
|
|
printers = settings.device.extras.bbl;
|
|
|
|
|
let devlist = $('print-bambu-device');
|
|
|
|
|
render_list(devlist);
|
|
|
|
|
$('bambu-output').style.display = 'flex';
|
2025-02-01 23:10:20 -05:00
|
|
|
$('print-bambu-1').onclick = function() {
|
|
|
|
|
gen3mf(zip => send(`${$('print-filename').value}.3mf`, zip, false));
|
|
|
|
|
}
|
|
|
|
|
$('print-bambu-2').onclick = function() {
|
|
|
|
|
gen3mf(zip => send(`${$('print-filename').value}.3mf`, zip, true));
|
|
|
|
|
api.modal.show('bambu');
|
2025-01-25 18:03:56 -05:00
|
|
|
}
|
2025-02-01 18:45:33 -05:00
|
|
|
devlist.onchange = () => {
|
|
|
|
|
let info = printers[devlist.value];
|
|
|
|
|
console.log({ selected: devlist.value, info });
|
|
|
|
|
host = info.host;
|
|
|
|
|
serial = info.serial;
|
|
|
|
|
password = info.code;
|
2025-02-01 23:10:20 -05:00
|
|
|
$('print-bambu-1').disabled =
|
|
|
|
|
$('print-bambu-2').disabled =
|
|
|
|
|
(host && serial && password) ? false : true;
|
|
|
|
|
get_ams_map(settings);
|
2025-02-01 18:45:33 -05:00
|
|
|
console.log({ bambu: host, serial, amsmap });
|
|
|
|
|
};
|
2025-01-25 18:03:56 -05:00
|
|
|
}
|
|
|
|
|
|
2025-02-01 23:10:20 -05:00
|
|
|
function send(filename, gcode, start) {
|
2025-01-25 18:03:56 -05:00
|
|
|
const baseUrl = '/api/bambu_send';
|
|
|
|
|
const url = new URL(baseUrl, window.location.origin);
|
|
|
|
|
url.searchParams.append('host', host);
|
2025-02-01 23:10:20 -05:00
|
|
|
url.searchParams.append('code', password);
|
2025-01-25 18:03:56 -05:00
|
|
|
url.searchParams.append('filename', filename);
|
|
|
|
|
url.searchParams.append('serial', serial);
|
|
|
|
|
url.searchParams.append('ams', amsmap);
|
2025-02-01 23:10:20 -05:00
|
|
|
url.searchParams.append('start', start ?? false);
|
2025-01-25 18:03:56 -05:00
|
|
|
|
|
|
|
|
const alert = api.alerts.show('Sending to Bambu Printer');
|
|
|
|
|
|
|
|
|
|
fetch(url.toString(), {
|
|
|
|
|
headers: { 'Content-Type': 'text/plain' },
|
|
|
|
|
method: 'POST',
|
|
|
|
|
body: gcode
|
|
|
|
|
}).then((response) => {
|
|
|
|
|
if (!response.ok) {
|
|
|
|
|
throw new Error(`HTTP error! Status: ${response.status}`);
|
|
|
|
|
}
|
|
|
|
|
api.alerts.hide(alert);
|
|
|
|
|
return response.json();
|
|
|
|
|
}).then(res => {
|
|
|
|
|
console.log('Bambu Send', res);
|
|
|
|
|
if (res.sent) {
|
|
|
|
|
api.alerts.show('File Sent', 3);
|
|
|
|
|
} else {
|
|
|
|
|
api.alerts.show('File Send Error', 3);
|
|
|
|
|
}
|
|
|
|
|
}).catch(error => {
|
|
|
|
|
console.error('Bambu Send Error', error);
|
|
|
|
|
api.alerts.show('File Send Error', 3);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
2025-01-28 12:45:35 -05:00
|
|
|
setInterval(monitor_keepalive, 5000);
|
|
|
|
|
|
2025-02-01 23:10:20 -05:00
|
|
|
api.bambu = { send, prep_export };
|
2025-01-25 18:03:56 -05:00
|
|
|
});
|