Hi, I have been looking for an sdk for the MP Voxel / FlashForge Adventurer 3 for nodejs and have found nothing decent but this. I am trying to make a server so I can print anything, anywhere. The code that I have copied and modified that for some reason, won't work. It works in your app, but not mine. The files below are the only ones used. Is there any way you could help me? Thanks!
conn.ts
import net from 'net';
import { EventEmitter } from 'events';
import codes from './codes';
import { crc32 } from 'crc';
import fs from 'fs';
class Connection extends EventEmitter {
socket: net.Socket;
conopt = {
host: '',
port: 0,
}
sending_gcode = false;
constructor(host: string, port: number) {
super();
this.socket = new net.Socket();
this.conopt = { host, port }
this.socket.on('data', (data) => {
this.emit('data', data);
const d = this.matchData(data);
if (d.cmd === 'M105') {
d.data = {
extruder: parseInt(d.data.match(/T0:([0-9]+)/)![1]),
bed: parseInt(d.data.match(/B:([0-9]+)/)![1]),
}
}
this.emit(d.cmd, d.data);
this.emit(codes[d.cmd], d.data);
});
this.socket.on('end', () => {
this.emit('end');
});
}
getTemperature() {
this.socket.write('~M105\n');
}
waitFor(cmd: string) {
return new Promise((resolve) => {
this.socket.on('data', (data) => {
if (data.toString().startsWith(cmd)) {
resolve(data);
}
});
});
}
matchData(data: Buffer): {
cmd: string,
data: any
} {
try {
const cmd = data.toString().match(new RegExp('CMD (?<CommandId>[MG][0-9]+) Received\.'));
if (cmd && cmd.groups && cmd.groups.CommandId) {
if (cmd.groups.CommandId === 'M28') this.sending_gcode = true;
if (cmd.groups.CommandId === 'M29') this.sending_gcode = false;
}
if (this.sending_gcode) return { cmd: 'M28', data: data.toString() };
return {
cmd: cmd!.groups!.CommandId,
data: data.toString().replace(new RegExp('CMD (?<CommandId>[MG][0-9]+) Received\.\r\n'), '')
}
} catch (e) {
console.log(e);
return {
cmd: '',
data: ''
}
}
}
writeCode(code: string, data: string = '') {
this.socket.write(`~${codes[code]} ${data}\r\n`);
}
connect() {
this.socket.connect(this.conopt)
}
printGCode(gcode: Buffer, name: string) {
console.log(gcode.length, name);
this.writeCode('file_start', `${gcode.length} 0:/user/${name}`);
let count = 0;
let offset = 0;
while (offset < gcode.length) {
let crc: number;
let packet: Buffer;
let dataSize = 0;
if (offset + 4096 < gcode.length) {
packet = gcode.subarray(offset, offset + 4096);
const crcResult = crc32(packet);
crc = crcResult;
console.log(crcResult.toString(16));
dataSize = 4096;
}
else {
// Every packet needs to be the same size, so zero pad the last one if we need to.
const actualLength = gcode.length - offset;
const data = gcode.subarray(offset, actualLength + offset);
// The CRC is for the un-padded data.
const crcResult = crc32(data);
crc = crcResult;
console.log(crc.toString(16));
packet = Buffer.alloc(4096);
for (let i = 0; i < data.length; ++i) {
packet.writeUInt32LE(data[i], i);
}
packet.fill(0, actualLength, 4096);
dataSize = actualLength;
}
// Always start each packet with four bytes
const bufferToSend = Buffer.alloc(4096 + 16);
bufferToSend.writeUInt16LE(0x5a, 0);
bufferToSend.writeUInt16LE(0x5a, 1);
bufferToSend.writeUInt16LE(0xef, 2);
bufferToSend.writeUInt16LE(0xbf, 3);
// Add the count of this packet, the size of the data it in (not counting padding) and the CRC.
bufferToSend.writeUInt32BE(count, 4);
bufferToSend.writeUInt32BE(dataSize, 8);
bufferToSend.writeUInt32BE(crc, 12);
// Add the data
for (let i = 0; i < packet.length; ++i) {
bufferToSend.writeUInt8(packet[i], i + 16);
}
// Send it to the printer
fs.appendFileSync('log.txt', `Sending packet ${count} ---\n${bufferToSend}\n---\n`);
this.socket.write(bufferToSend);
offset += 4096;
++count;
}
this.socket.write('\n');
this.writeCode('file_end');
}
}
export default Connection;
codes.ts
export default {
M601: 'start',
M602: 'end',
M115: 'info',
M119: 'endstop',
M105: 'temp',
M27: 'status',
M146: 'led',
M23: 'print',
M36: 'stop',
M28: 'file_start',
M29: 'file_end',
M108: 'stop_heat',
M651: 'fan_on',
M652: 'fan_off',
M114: 'position',
M112: 'estop',
M18: 'motor_stop',
M17: 'motor_start',
G92: 'set_zero',
M610: 'change_name',
G1: 'bed_move',
M140: 'bed_temp',
M104: 'extruder_temp',
start: 'M601',
end: 'M602',
info: 'M115',
endstop: 'M119',
temp: 'M105',
status: 'M27',
led: 'M146',
print: 'M23',
stop: 'M36',
file_start: 'M28',
file_end: 'M29',
stop_heat: 'M108',
fan_on: 'M651',
fan_off: 'M652',
position: 'M114',
estop: 'M112',
motor_stop: 'M18',
motor_start: 'M17',
set_zero: 'G92',
change_name: 'M610',
bed_move: 'G1',
bed_temp: 'M140',
extruder_temp: 'M104',
} as Record<string, string>;