|
1 | | -<div align="center"> |
2 | | - <h1>FlashForge TypeScript API</h1> |
3 | | - <p> |
4 | | - <img src="https://img.shields.io/badge/typescript-%23007ACC.svg?style=for-the-badge&logo=typescript&logoColor=white" alt="TypeScript"> |
5 | | - <img src="https://img.shields.io/badge/node.js-6DA55F?style=for-the-badge&logo=node.js&logoColor=white" alt="Node.js"> |
6 | | - <img src="https://img.shields.io/badge/pnpm-8F0B8B?style=for-the-badge&logo=pnpm&logoColor=white" alt="pnpm"> |
7 | | - <img src="https://img.shields.io/badge/-jest-%23C21325?style=for-the-badge&logo=jest&logoColor=white" alt="Jest"> |
8 | | - <img src="https://img.shields.io/badge/axios-671ddf?style=for-the-badge&logo=axios&logoColor=white" alt="Axios"> |
9 | | - </p> |
10 | | - <p> |
11 | | - <img src="https://img.shields.io/github/stars/GhostTypes/ff-5mp-api-ts.svg?style=for-the-badge&labelColor=black&color=yellow" alt="Stars"> |
12 | | - <img src="https://img.shields.io/github/forks/GhostTypes/ff-5mp-api-ts.svg?style=for-the-badge&labelColor=black&color=blue" alt="Forks"> |
13 | | - </p> |
14 | | - <p> |
15 | | - A robust, cross-platform API for FlashForge 3D printers, created through |
16 | | - reverse-engineering the communication between the printers and FlashForge software. |
17 | | - </p> |
18 | | - <p> |
19 | | - <a href="docs/README.md"><strong>Explore the Docs »</strong></a> |
20 | | - </p> |
21 | | -</div> |
| 1 | +# FlashForge TypeScript API |
22 | 2 |
|
| 3 | +TypeScript and Node.js library for controlling FlashForge 3D printers over the modern HTTP API and the legacy TCP protocol. |
23 | 4 |
|
24 | | -<br> |
25 | | -<div align="center"> |
26 | | - <h2>Printer Coverage & Testing</h2> |
27 | | -</div> |
| 5 | +## Supported Printers |
28 | 6 |
|
29 | | -<div align="center"> |
30 | | -<table> |
31 | | - <tr> |
32 | | - <th>Printer</th> |
33 | | - <th>Supported</th> |
34 | | - <th>Tested</th> |
35 | | - <th>API</th> |
36 | | - </tr> |
| 7 | +| Printer | Support | |
| 8 | +| --- | --- | |
| 9 | +| Adventurer 5M | Full | |
| 10 | +| Adventurer 5M Pro | Full | |
| 11 | +| AD5X | Full | |
| 12 | +| Adventurer 3 / 4 | TCP support | |
37 | 13 |
|
38 | | - <tr> |
39 | | - <td><strong>Adventurer 5X</strong></td> |
40 | | - <td>Yes</td> |
41 | | - <td>Yes</td> |
42 | | - <td>HTTP + TCP</td> |
43 | | - </tr> |
| 14 | +## Installation |
44 | 15 |
|
45 | | - <tr> |
46 | | - <td><strong>Adventurer 5M / 5M Pro</strong></td> |
47 | | - <td>Yes</td> |
48 | | - <td>Yes</td> |
49 | | - <td>HTTP + TCP</td> |
50 | | - </tr> |
51 | | - |
52 | | - <tr> |
53 | | - <td><strong>Adventurer 3 / 4</strong></td> |
54 | | - <td>Yes</td> |
55 | | - <td>Partial</td> |
56 | | - <td>TCP Only</td> |
57 | | - </tr> |
58 | | -</table> |
59 | | -</div> |
60 | | - |
61 | | -<br> |
62 | | - |
63 | | -<div align="center"> |
64 | | - <h2>Feature Coverage</h2> |
65 | | -</div> |
66 | | - |
67 | | -<div align="center"> |
68 | | -<table> |
69 | | - <tr> |
70 | | - <th>Feature</th> |
71 | | - <th>TCP Only</th> |
72 | | - <th>TCP + HTTP</th> |
73 | | - </tr> |
74 | | - |
75 | | - <tr> |
76 | | - <td>Get Recent & Local Files</td> |
77 | | - <td>Yes</td> |
78 | | - <td>Yes</td> |
79 | | - </tr> |
80 | | - |
81 | | - <tr> |
82 | | - <td>Model Preview Images</td> |
83 | | - <td>Yes (Slow)</td> |
84 | | - <td>Yes (Fast)</td> |
85 | | - </tr> |
86 | | - |
87 | | - <tr> |
88 | | - <td>Full Job Control<br><small>(Start / Stop / Pause / Resume)</small></td> |
89 | | - <td>Yes</td> |
90 | | - <td>Yes</td> |
91 | | - </tr> |
92 | | - |
93 | | - <tr> |
94 | | - <td>LED Control</td> |
95 | | - <td>Yes</td> |
96 | | - <td>Yes</td> |
97 | | - </tr> |
98 | | - |
99 | | - <tr> |
100 | | - <td>Upload New Files</td> |
101 | | - <td>No (Not planned)</td> |
102 | | - <td>Yes</td> |
103 | | - </tr> |
104 | | - |
105 | | - <tr> |
106 | | - <td>Printer Information</td> |
107 | | - <td>Limited</td> |
108 | | - <td>Yes</td> |
109 | | - </tr> |
110 | | - |
111 | | - <tr> |
112 | | - <td>Job Information</td> |
113 | | - <td>Very Limited</td> |
114 | | - <td>Yes</td> |
115 | | - </tr> |
116 | | - |
117 | | - <tr> |
118 | | - <td>Job Time & ETA</td> |
119 | | - <td>Not Available</td> |
120 | | - <td>Yes</td> |
121 | | - </tr> |
122 | | - |
123 | | - <tr> |
124 | | - <td>Homing / Direct G&M Code Control</td> |
125 | | - <td>Yes</td> |
126 | | - <td>Yes</td> |
127 | | - </tr> |
128 | | -</table> |
129 | | -</div> |
130 | | - |
131 | | -<br> |
132 | | - |
133 | | -<div align="center"> |
134 | | - <h2>Getting Started</h2> |
135 | | - <p> |
136 | | - This section covers how to use the API with both legacy FlashForge printers and |
137 | | - newer models such as the Adventurer 5M / 5M Pro and AD5X. |
138 | | - </p> |
139 | | -</div> |
140 | | - |
141 | | -<br> |
142 | | - |
143 | | -<div align="center"> |
144 | | - <h3>Legacy Printers (Adventurer 3 / 4)</h3> |
145 | | - <p> |
146 | | - Legacy FlashForge printers use a TCP-based protocol which provides basic job control, |
147 | | - printer information, and status monitoring. Connecting only requires the printer’s IP address. |
148 | | - </p> |
149 | | -</div> |
150 | | - |
151 | | -```typescript |
152 | | -import { FlashForgeClient } from 'ff-api'; |
153 | | - |
154 | | -async function main() { |
155 | | - // Replace with your printer's IP address |
156 | | - const client = new FlashForgeClient('192.168.1.100'); |
157 | | - |
158 | | - if (await client.initControl()) { |
159 | | - console.log("Successfully connected to printer."); |
160 | | - |
161 | | - // Example: Turn on the LED |
162 | | - await client.ledOn(); |
| 16 | +```bash |
| 17 | +npm install @ghosttypes/ff-api |
| 18 | +``` |
163 | 19 |
|
164 | | - // Example: Get printer info |
165 | | - const info = await client.getPrinterInfo(); |
166 | | - if (info) { |
167 | | - console.log(`Printer Type: ${info.TypeName}`); |
168 | | - console.log(`Firmware: ${info.FirmwareVersion}`); |
169 | | - } |
| 20 | +## Quick Start |
170 | 21 |
|
171 | | - await client.dispose(); |
172 | | - } else { |
173 | | - console.log("Failed to connect to printer."); |
174 | | - } |
175 | | -} |
| 22 | +### Modern Printers |
176 | 23 |
|
177 | | -main(); |
178 | | -``` |
179 | | -<br> |
180 | | -<div align="center"> |
181 | | - <h3>Adventurer 5M / 5M Pro</h3> |
182 | | - <p> The Adventurer 5 series uses an improved HTTP API for fast, modern communication, while still supporting legacy TCP-based G-code control. You will need the printer’s <strong>IP address</strong>, <strong>serial number</strong>, and <strong>check code</strong></p> |
183 | | -</div> |
| 24 | +Use `FiveMClient` for Adventurer 5M, 5M Pro, and AD5X. |
184 | 25 |
|
185 | 26 | ```typescript |
186 | | -import { FiveMClient } from 'ff-api'; |
| 27 | +import { FiveMClient } from '@ghosttypes/ff-api'; |
187 | 28 |
|
188 | 29 | async function main() { |
189 | | - // Replace with your printer's details |
190 | | - const client = new FiveMClient( |
191 | | - '192.168.1.101', |
192 | | - 'SNADVA5M12345', |
193 | | - '12345' |
194 | | - ); |
| 30 | + const client = new FiveMClient('192.168.1.100', 'SERIAL_NUMBER', 'CHECK_CODE'); |
195 | 31 |
|
196 | | - if (await client.initialize()) { |
197 | | - console.log("Successfully connected to printer."); |
198 | | - console.log(`Printer Name: ${client.printerName}`); |
199 | | - console.log(`Firmware: ${client.firmwareVersion}`); |
| 32 | + if (!(await client.initialize())) { |
| 33 | + return; |
| 34 | + } |
200 | 35 |
|
201 | | - // Example: Get a list of local files |
202 | | - const files = await client.files.getLocalFiles(); |
203 | | - if (files) { |
204 | | - console.log("Files on printer:", files.map(f => f.name)); |
205 | | - } |
| 36 | + await client.initControl(); |
206 | 37 |
|
207 | | - // Example: Upload a file |
208 | | - // await client.files.uploadFile('path/to/your/file.gcode'); |
| 38 | + console.log(`Printer: ${client.printerName}`); |
| 39 | + console.log(`Firmware: ${client.firmwareVersion}`); |
209 | 40 |
|
210 | | - // The FiveMClient also includes the legacy TCP client for direct G-code |
211 | | - await client.tcpClient.homeAxes(); |
| 41 | + const status = await client.info.get(); |
| 42 | + console.log(`State: ${status?.Status}`); |
212 | 43 |
|
213 | | - await client.dispose(); |
214 | | - } else { |
215 | | - console.log("Failed to connect."); |
216 | | - } |
| 44 | + await client.control.homeAxes(); |
| 45 | + await client.dispose(); |
217 | 46 | } |
218 | 47 |
|
219 | 48 | main(); |
220 | 49 | ``` |
221 | 50 |
|
222 | | -<div align="center"> |
223 | | - <h3>Adventurer 5X (AD5X)</h3> |
224 | | - <p>The AD5X uses the same powerful HTTP API as the 5M series but adds specialized support for its <strong>Intelligent Filament Station (IFS)</strong>, enabling multi-color and multi-material printing. The API provides dedicated methods and data models to manage this functionality.</p> |
225 | | - <p> Connecting to an AD5X is identical to a standard 5M. </p> |
226 | | -</div> |
227 | | - |
228 | | -```typescript |
229 | | -import { FiveMClient } from 'ff-api'; |
230 | | - |
231 | | -async function checkIFS() { |
232 | | - const client = new FiveMClient('192.168.1.102', 'SNADVA5X12345', '54321'); |
233 | | - if (!await client.initialize() || !client.isAD5X) { |
234 | | - console.log("Failed to connect or not an AD5X."); |
235 | | - return; |
236 | | - } |
237 | | - |
238 | | - const machineInfo = client.info.machineInfo; |
239 | | - |
240 | | - if (machineInfo && machineInfo.HasMatlStation && machineInfo.MatlStationInfo) { |
241 | | - console.log("Intelligent Filament Station (IFS) Detected."); |
242 | | - |
243 | | - const ifs = machineInfo.MatlStationInfo; |
244 | | - console.log(`- Active Slot: ${ifs.currentSlot}`); |
245 | | - console.log(`- Loading Slot: ${ifs.currentLoadSlot}`); |
246 | | - console.log("- Slot Details:"); |
247 | | - |
248 | | - for (const slot of ifs.slotInfos) { |
249 | | - if (slot.hasFilament) { |
250 | | - console.log(` - Slot ${slot.slotId}: [${slot.materialName}] - Color: ${slot.materialColor}`); |
251 | | - } else { |
252 | | - console.log(` - Slot ${slot.slotId}: [Empty]`); |
253 | | - } |
254 | | - } |
255 | | - } else { |
256 | | - console.log("No Intelligent Filament Station detected."); |
257 | | - } |
258 | | - |
259 | | - await client.dispose(); |
260 | | -} |
261 | | - |
262 | | -checkIFS(); |
263 | | -``` |
| 51 | +### Legacy TCP Printers |
264 | 52 |
|
265 | | -<div align="center"> <h4>Starting a Multi-Color Print</h4> <p> To start a multi-color print, you need to provide <code>materialMappings</code>. This array links the tool ID from your G-code file to a specific slot in the material station. </p> <p> - <code>toolId</code>: The tool index from your slicing software (0-3). |
266 | | - |
267 | | - |
268 | | -- <code>slotId</code>: The physical slot on the material station (1-4). </p> </div> |
| 53 | +Use `FlashForgeClient` for direct TCP control on older printers. |
269 | 54 |
|
270 | 55 | ```typescript |
271 | | -import { FiveMClient, AD5XLocalJobParams, AD5XMaterialMapping } from 'ff-api'; |
272 | | - |
273 | | -async function startMultiColor() { |
274 | | - const client = new FiveMClient('192.168.1.102', 'SNADVA5X12345', '54321'); |
275 | | - if (!await client.initialize() || !client.isAD5X) { |
276 | | - console.log("Failed to connect or not an AD5X."); |
277 | | - return; |
278 | | - } |
| 56 | +import { FlashForgeClient } from '@ghosttypes/ff-api'; |
279 | 57 |
|
280 | | - const mappings: AD5XMaterialMapping[] = [ |
281 | | - { toolId: 0, slotId: 1, materialName: "PLA", toolMaterialColor: "#FF0000", slotMaterialColor: "#FF0000" }, |
282 | | - { toolId: 1, slotId: 2, materialName: "PLA", toolMaterialColor: "#00FF00", slotMaterialColor: "#00FF00" } |
283 | | - ]; |
284 | | - |
285 | | - const jobParams: AD5XLocalJobParams = { |
286 | | - fileName: 'my_multi_color_print.gcode', |
287 | | - levelingBeforePrint: true, |
288 | | - materialMappings: mappings |
289 | | - }; |
| 58 | +async function main() { |
| 59 | + const client = new FlashForgeClient('192.168.1.101'); |
290 | 60 |
|
291 | | - if (await client.jobControl.startAD5XMultiColorJob(jobParams)) { |
292 | | - console.log("Multi-color job started successfully!"); |
293 | | - } |
| 61 | + if (await client.initControl()) { |
| 62 | + const info = await client.getPrinterInfo(); |
| 63 | + console.log(info?.TypeName); |
| 64 | + } |
294 | 65 |
|
295 | | - await client.dispose(); |
| 66 | + await client.dispose(); |
296 | 67 | } |
297 | | -``` |
298 | 68 |
|
299 | | -<div align="center"> <h4>Starting a Single-Color Print</h4> <p> For single-color prints, you can use a simpler method that doesn't require material mappings. The printer will use the currently loaded filament. </p> </div> |
300 | | - |
301 | | -```typescript |
302 | | -import { FiveMClient, AD5XSingleColorJobParams } from 'ff-api'; |
| 69 | +main(); |
| 70 | +``` |
303 | 71 |
|
304 | | -async function startSingleColor() { |
305 | | - const client = new FiveMClient('192.168.1.102', 'SNADVA5X12345', '54321'); |
306 | | - if (!await client.initialize() || !client.isAD5X) { |
307 | | - console.log("Failed to connect or not an AD5X."); |
308 | | - return; |
309 | | - } |
| 72 | +## Main Entry Points |
310 | 73 |
|
311 | | - const jobParams: AD5XSingleColorJobParams = { |
312 | | - fileName: 'my_single_color_print.gcode', |
313 | | - levelingBeforePrint: true |
314 | | - }; |
| 74 | +- `FiveMClient`: modern HTTP + TCP client for 5M, 5M Pro, and AD5X |
| 75 | +- `PrinterDiscovery`: UDP discovery for supported FlashForge printers |
| 76 | +- `FlashForgeClient`: lower-level TCP client for legacy printers and direct G-code workflows |
315 | 77 |
|
316 | | - if (await client.jobControl.startAD5XSingleColorJob(jobParams)) { |
317 | | - console.log("Single-color job started successfully!"); |
318 | | - } |
| 78 | +## Capabilities |
319 | 79 |
|
320 | | - await client.dispose(); |
321 | | -} |
322 | | -``` |
| 80 | +- printer discovery |
| 81 | +- printer status and machine information |
| 82 | +- job control |
| 83 | +- file listing, uploads, and thumbnails |
| 84 | +- temperature and motion control |
| 85 | +- LED, camera, and filtration control where supported |
| 86 | +- AD5X-specific job and material-station support |
323 | 87 |
|
324 | | -<div align="center"> <h4>Uploading Files for AD5X</h4> <p> You can also upload files with material mappings directly using <code>uploadFileAD5X</code>. The material mappings are Base64-encoded and sent in the headers automatically. </p> </div> |
| 88 | +## Documentation |
325 | 89 |
|
| 90 | +- [docs/README.md](docs/README.md) |
| 91 | +- [docs/clients.md](docs/clients.md) |
| 92 | +- [docs/modules.md](docs/modules.md) |
| 93 | +- [docs/protocols.md](docs/protocols.md) |
0 commit comments