-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgcode.ts
More file actions
125 lines (106 loc) · 2.91 KB
/
gcode.ts
File metadata and controls
125 lines (106 loc) · 2.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/**
* Set of GCode commands
*
* @export
* @enum {number}
*/
export enum GCommand {
COMMENT = ';',
SET_FAN_SPEED = 'M106',
TURN_OFF_FAN = 'M107',
MOVE = 'G1',
ABSOLUTE_POSITIONING = 'G90',
RELATIVE_POSITIONING = 'G91',
ABSOLUTE_EXTRUSION = 'M82',
RELATIVE_EXTRUSION = 'M83',
SET_POSITION = 'G92',
SET_DEFAULT_ACCELERATION = 'M204',
}
/**
* GCode class represents gcode command with its parameters
*
* @export
* @class GCommand
*/
export class GCode {
/**
* GCode command
*
* @public
* @type {(GCommand | string)}
*/
public command: GCommand | string = '';
/**
* GCode that constructor was provided with if `commandOnly` set to `true`
*
* @public
* @type {string}
*/
public rawCode: string = '';
/**
* Parameters of this gcode
*
* @public
* @type {Record<string, string>}
*/
public params: Record<string, string> = {};
/**
* Creates an instance of GCode.
*
* @constructor
* @param {string} [encodedCommand=''] GCode to parse if any
* @param {boolean} [commandOnly=false] Whether to parse only command and skip parameters.
*/
constructor(encodedCommand: string = '', commandOnly: boolean = false) {
if (commandOnly) this.rawCode = encodedCommand;
if (!encodedCommand.trim()) return;
let commentBegan = false;
for (const [index, part] of encodedCommand.split(' ').entries()) {
if (!part && !commentBegan) continue;
const isComment = part.startsWith(GCommand.COMMENT);
if (index === 0) {
this.command = isComment ? GCommand.COMMENT : part;
if (commandOnly) break;
}
if (commentBegan || isComment) {
commentBegan = true;
if (GCommand.COMMENT in this.params) this.params[GCommand.COMMENT] += ' ' + part;
else this.params[GCommand.COMMENT] = part.substring(1);
continue;
}
if (index > 0) {
let variable = '',
value = '';
if (part.includes('=')) {
// Klipper-style
[variable, value] = part.split('=');
} else {
// RepRap-style
[variable, value] = [part[0], part.slice(1)];
}
this.params[variable.toUpperCase()] = value;
}
}
}
/**
* Encodes gcode command and its parameters into a string with trailing newline character.
*
* If gcode was constructed with `commandOnly = true`, function outputs original string
*
* @returns {string}
*/
toString(): string {
if (this.rawCode) return this.rawCode.trim() + '\n';
const commandParts: string[] = [];
if (this.command !== GCommand.COMMENT) commandParts.push(this.command);
for (const param in this.params) {
let encodedParam = param;
if (this.params[param]) {
encodedParam += param.length > 1 ? '=' : '';
encodedParam += this.params[param];
}
commandParts.push(encodedParam);
}
return commandParts.join(' ') + '\n';
}
}