Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

bambu-cli

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

bambu-cli - npm Package Compare versions

Comparing version 1.0.11 to 1.0.12

docs/parser.png

15

bin/cli.js

@@ -23,5 +23,8 @@ #!/usr/bin/env node

.describe('parse', 'Parse a 3mf file after download')
.describe('set', 'For config, key to set')
.describe('slim', 'Limit fields on status')
.describe('upload', 'Upload a file [--upload=./foo.gcode.3mf]')
.describe('value', 'For config, value to set with --key')
.describe('yes', 'Auto select YES when prompted')
.command('config', 'Show config (for bambu-farm)')
.command('config', 'Show config (for bambu-farm) [--set foo --value bar]')
.command('files', 'Show gcode files on machine [--id] [--filter] [--download] [--parse] [--delete] [--yes]')

@@ -34,3 +37,3 @@ .command('login', 'Login and fetch machine information')

//.command('print', 'Pass file name on printer to print [--file]')
.command('status', 'Check machine connectivity [--id to get detailed info]')
.command('status', 'Check machine connectivity [--id to get detailed info] [--slim]')
.command('timelapse', 'Show video files on machine [--id] [--filter] [--download] [--delete] [--yes]')

@@ -44,2 +47,10 @@ .command('upload', 'Upload a .gcode or .gcode.3mf file [--id] [--upload]')

if (args.slim) {
args.slim = cfg.fixValue(args.slim);
}
if (config.slim && !('slim' in args)) { //TODO make this more dynamic
args.slim = config.slim;
}
//Machine alias resolving..

@@ -46,0 +57,0 @@ const machines = config.machines;

@@ -12,3 +12,6 @@ const fs = require('fs');

//Default command..
module.exports = () => {
module.exports = (args) => {
if (args.set && args.value) {
module.exports.set(args.set, args.value);
}
console.log(JSON.stringify(config, null, 4));

@@ -50,3 +53,18 @@ };

const fixValue = (value) => {
if (value === 'null') {
value = null;
}
if (value === 'false') {
value = false;
}
if (value === 'true') {
value = true;
}
return value;
};
module.exports.fixValue = fixValue;
module.exports.set = (key, value) => {
value = fixValue(value);
config[key] = value;

@@ -53,0 +71,0 @@ if (value === null) {

4

lib/const.js

@@ -74,6 +74,6 @@ // From https://github.com/greghesp/ha-bambulab

"cool_plate": "Cool Plate",
"eng_plate": "Engineering Plate",
"eng_plate": "Eng Plate",
"hot_plate": "Hot Plate",
"textured_plate": "Textured Plate"
"textured_plate": "Text Plate"
};
module.exports.PLATES = PLATES;

@@ -36,2 +36,7 @@ const path = require('path');

if (file.indexOf('.gcode') === -1) {
args.force = true;
console.log(`⚠️ Warning, this is not a prepared file. No gcode, colors, filament, etc data is available. ⚠️\n`);
}
if (fs.existsSync(cacheFile) && !args.force) {

@@ -49,2 +54,35 @@ console.log(`Loading cached data from: ${cacheFile}`);

.on('entry', async(entry) => {
if (entry.path === 'Metadata/model_settings.config') {
const content = await entry.buffer();
const options = {
ignoreAttributes: false,
attributeNamePrefix: "",
isArray: (name, jpath, isLeafNode, isAttribute) => {
if (jpath === 'config.plate') {
return true;
}
}
};
const parser = new XMLParser(options);
const json = parser.parse(content);
//console.log(content.toString());
//console.log(JSON.stringify(json.config.plate, null, 4));
json.config.plate.forEach(p => {
const meta = p.metadata;
let id;
let name;
meta.forEach(m => {
if (m.key === 'plater_id') {
id = Number(m.value);
}
if (m.key === 'plater_name') {
name = m.value;
}
});
//console.log(`Plate ${id} (${name})`);
const plate = `plate_${id}`;
info[plate] = info[plate] || {};
info[plate].name = name;
});
}
if (entry.path === 'Metadata/slice_info.config') {

@@ -125,7 +163,19 @@ const content = await entry.buffer();

.on('end', () => {
saveCache(cacheFile, info);
printData(file, info, cb);
const _info = filterData(info);
//console.log(JSON.stringify(_info, null, 4));
saveCache(cacheFile, _info);
printData(file, _info, cb);
});
};
const filterData = (info) => {
Object.keys(info).forEach(plate => {
const len = Object.keys(info[plate]).length;
if (len === 1) {
delete info[plate];
}
});
return info;
};
const saveCache = (file, info) => {

@@ -140,3 +190,5 @@ //console.log(`Saving parse data to cache: ${file}`);

console.log();
const type = (file.indexOf('.gcode') > -1) ? 'GCode Ready to Print' : 'Simple Project File (not ready to print)';
console.log(`File Information:`);
console.log(` Type: ${type}`);
console.log(` Size: ${pretty(stat.size)}`);

@@ -149,3 +201,3 @@ console.log(` Created: ${stat.ctime.toLocaleString()}`);

Object.values(info).forEach(i => {
table.cell('Plate Name', `Plate ${i.plate}`);
table.cell('Plate', `Plate ${i.plate}`);
table.cell('Bed Type', i.bed);

@@ -162,2 +214,4 @@ table.cell('Nozzle', i.nozzle);

console.log(table.toString());
findPrinter(info);
console.log();
console.log(`Finished parsing in ${timer(START)}`);

@@ -168,2 +222,98 @@ cb && cb();

const findPrinter = (info) => {
const machines = cfg.get('machines');
//console.log(machines);
//console.log(JSON.stringify(info, null, 4));
const colors = {};
const valid = {};
Object.values(info).forEach(i => {
i.filaments.forEach(f => {
const key = `${f.type}:::${f.color.replace('#', '')}`;
colors[key] = 1;
});
});
const _colors = [];
Object.keys(colors).forEach((c) => {
_colors.push(c.split(':::').join(' #'));
});
console.log(`File has filament type/colors of:\n\t${_colors.join(', ')}`);
console.log();
machines.forEach(m => {
valid[m.id] = valid[m.id] || [];
m.filaments.forEach(f => {
const key = `${f.type}:::${f.color}`;
if (colors[key]) {
//console.log(key);
valid[m.id].push(key);
}
});
});
Object.values(valid).forEach(v => {
v.forEach(k => {
delete colors[k];
});
});
if (colors.length) {
console.error(`⚠️ No printers found with these colors: ${colors.join(', ')}`);
}
Object.values(info).forEach((pl) => {
//console.log(pl);
const avail = [];
Object.keys(valid).forEach(id => {
//console.log(pl.plate, id, pl.filaments);
pl.filaments.forEach(f => {
const key = `${f.type}:::${f.color.replace('#', '')}`;
//console.log('key', key);
Object.keys(valid).forEach(id => {
//console.log(id, key, valid[id], valid[id].includes(key));
if (valid[id].includes(key)) {
let has = false;
avail.forEach(k => {
if (k.id === id && k.filament === key) {
has = true;
}
});
if (!has) {
avail.push({
id: id,
filament: key
});
}
}
});
});
});
const per = {};
avail.forEach(v => {
per[v.id] = per[v.id] || [];
per[v.id].push(v.filament);
});
//console.log(`Plate ${pl.plate}`, avail, per, pl.colors.length);
let num = 0;
let ps = 'None';
Object.keys(per).forEach(id => {
const values = per[id];
//console.log(id, values);
if (values.length === pl.colors.length) {
if (!Array.isArray(ps)) {
ps = [];
}
num++;
ps.push(id);
}
});
if (Array.isArray(ps)) {
ps = ps.join(', ');
}
if (num > 0) {
console.log(`Plate ${pl.plate} can be printed on ${num} printer${(num > 1) ? 's' : ''}: ${ps}`);
} else {
console.log(`⚠️ No capable printers found for Plate ${pl.plate}.`);
}
});
//console.log(valid);
//console.log(colors);
//console.log(info);
};
module.exports = parse;

@@ -174,5 +324,4 @@

c.forEach((name, id) => {
const color = chalk.bgHex(name)(' ');
const color = chalk.bgHex(name)(' ');
c[id] = `${color} ${name}`;
});

@@ -191,3 +340,3 @@ }

});
return info.join(', ');
return dedupe(info).join(', ');
};

@@ -194,0 +343,0 @@

@@ -28,9 +28,9 @@ const cfg = require('./config.js');

}
return showAll([m]);
return showAll(args, [m]);
}
showAll(machines);
showAll(args, machines);
};
const showAll = (_machines) => {
const showAll = (args, _machines) => {
const len = _machines.length;

@@ -43,4 +43,12 @@ let machines = JSON.parse(JSON.stringify(_machines));

const table = new Table();
let showExt = false;
const slim = (len === 1) ? false : (args.slim || false);
Object.keys(statusCheck).forEach(id => {
const m = statusCheck[id];
if (m.external.color && m.external.type) {
showExt = true;
}
});
Object.keys(statusCheck).forEach(id => {
const m = statusCheck[id];
let ams = 'n/a';

@@ -58,11 +66,16 @@ if (m.ams && Array.isArray(m.ams.ams)) {

const c = chalk.bgHex(m.external.color)(' ');
ext = `${c} #${m.external.color}/${m.external.type}`;
}
table.cell('ID', m.machine.id);
if (!slim) {
table.cell('ID', m.machine.id);
}
table.cell('Name', m.machine.name);
table.cell('IP Address', m.machine.ip);
if (!slim) {
table.cell('IP Address', m.machine.ip);
}
table.cell('FTP', status(m.ftp));
table.cell('MQTT', status(m.mqtt));
table.cell('Ext Spool', ext);
if (showExt) {
table.cell('Ext Spool', ext);
}
table.cell('AMS', ams);

@@ -91,2 +104,5 @@ table.cell('Nozzle', m.nozzle);

const s = statusCheck[m.id];
if (!s) {
return; //Machine isn't in status, skip it..
}
m.ams = 0;

@@ -100,3 +116,3 @@ delete m.colors;

}
if (s && s.ams) {
if (s && s.ams && s.ams.ams && Array.isArray(s.ams.ams)) {
m.ams = s.ams.ams.length;

@@ -162,3 +178,3 @@ s.ams.ams.forEach((a) => {

const table = new Table();
let tc = 1;
let tc = 0;
ams.forEach(a => {

@@ -341,2 +357,4 @@ const amsID = amsNumToLetter(a.id);

.replace(', 0 seconds', '')
.replace('ays', '')
.replace('ay', '')
.replace('econds', '')

@@ -343,0 +361,0 @@ .replace('ours', '')

{
"name": "bambu-cli",
"version": "1.0.11",
"version": "1.0.12",
"description": "Bambulabs CLI for printers",

@@ -5,0 +5,0 @@ "keywords": [

@@ -149,24 +149,8 @@ # bambu-cli

This will parse a local `.gcode.3mf` file and show some details about it.
This will parse a local `.gcode.3mf` file and show some details about it. Just added checking filaments against currently known printers and reporting which one a plate can be sent to.
bambu-cli parse --file "./DL-44 Blaster.gcode.3mf"
Attempting to parse: ./DL-44 Blaster.gcode.3mf
<img src="https://github.com/davglass/bambu-cli/blob/main/docs/parser.png?raw=true">
<img src="https://github.com/davglass/bambu-cli/blob/main/docs/parser2.png?raw=true">
File Information:
Size: 33.9 MB
Created: 12/18/2023, 8:52:26 AM
Last Mod: 12/18/2023, 8:52:26 AM
Last Access: 12/18/2023, 8:52:26 AM
Plate Name Bed Type Nozzle Filament Colors Filaments Fil Used (m) Fil Used (g) GCode Lines Estimated Time
---------- -------------- ------ ---------------------- ---------- ------------ ------------- ----------- --------------
Plate 1 Textured Plate 0.4 #000000 PLA 12.15 38.57 547,215 2h 45m 14s
Plate 2 Textured Plate 0.4 #000000, #FFFFFF PLA, PLA-S 24.82, 1.19 78.79, 3.74 1,056,541 6h 32m 8s
Plate 3 Textured Plate 0.4 #D3B7A7, #FFFFFF PLA, PLA-S 10.52, 0.11 33.41, 0.35 642,166 2h 25m 6s
Plate 4 Textured Plate 0.4 #D3B7A7, #FFFFFF PLA, PLA-S 2.07, 0.10 6.56, 0.31 164,146 34m 10s
Plate 5 Textured Plate 0.4 #9B9EA0 PLA 6.31 20.03 745,572 2h 27m 42s
Plate 6 Textured Plate 0.4 #000000 PLA 9.00 28.56 680,367 3h 19m 21s
Plate 7 Textured Plate 0.4 #000000, #FFFFFF PLA, PLA-S 44.75, 9.45 142.09, 29.55 1,682,337 13h 39m 14s
## Upload

@@ -173,0 +157,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc