@@ -32,17 +32,11 @@ export class PrinterInfo {
3232 * provides a piece of information in a "Key: Value" format.
3333 *
3434 * Parsing logic:
35- * - Splits the replay by newline characters.
36- * - Line 1 (data[0]): Usually command echo/header, often ignored or assumed specific format.
37- * - Line 2 (data[1]): Expected to be "Machine Type: [TypeName]". `getRight` extracts the value.
38- * - Line 3 (data[2]): Expected to be "Machine Name: [Name]". `getRight` extracts the value.
39- * - Line 4 (data[3]): Expected to be "Firmware: [FirmwareVersion]". `getRight` extracts the value.
40- * - Line 5 (data[4]): Expected to be "SN: [SerialNumber]". `getRight` extracts the value.
41- * - Line 6 (data[5]): Expected to be the dimensions string directly (e.g., "X:220 Y:220 Z:220").
42- * - Line 7 (data[6]): Expected to be "Tool count: [ToolCount]". `getRight` extracts the value.
43- * - Line 8 (data[7]): Expected to be "Mac Address:[MacAddress]". The prefix is removed.
44- *
45- * The `getRight` helper function is used to extract the value part after the colon for several lines.
35+ * - Splits the replay by newline characters, trims each line, and filters out blank lines.
36+ * - Iterates through lines matching known prefixes (Machine Type, Machine Name, Firmware, etc.).
37+ * - This approach is resilient to blank lines, extra whitespace, and minor formatting variations
38+ * across different printer firmware versions (e.g., Adventurer 3C Pro inserts a blank line
39+ * between Machine Name and Firmware).
4640 *
4741 * @param replay The raw multi-line string response from the M115 command.
4842 * @returns The populated `PrinterInfo` instance, or null if parsing fails
@@ -52,47 +46,41 @@ export class PrinterInfo {
5246 if ( ! replay ) return null ;
5347
5448 try {
55- const data = replay . split ( '\n' ) ;
56- // Assumes data[0] is "CMD M115 Received." or similar header.
49+ const lines = replay
50+ . split ( '\n' )
51+ . map ( ( line ) => line . trim ( ) )
52+ . filter ( ( line ) => line . length > 0 && line !== 'ok' ) ;
5753
58- const name = getRight ( data [ 1 ] ) ; // Expected: "Machine Type: Adventurer 5M Pro"
59- if ( name === null ) {
60- console . log ( 'PrinterInfo replay has null Machine Type' ) ;
61- return null ;
54+ for ( const line of lines ) {
55+ if ( line . startsWith ( 'Machine Type:' ) ) {
56+ this . TypeName = line . replace ( 'Machine Type:' , '' ) . trim ( ) ;
57+ } else if ( line . startsWith ( 'Machine Name:' ) ) {
58+ this . Name = line . replace ( 'Machine Name:' , '' ) . trim ( ) ;
59+ } else if ( line . startsWith ( 'Firmware:' ) ) {
60+ this . FirmwareVersion = line . replace ( 'Firmware:' , '' ) . trim ( ) ;
61+ } else if ( line . startsWith ( 'SN:' ) || line . startsWith ( 'Serial Number:' ) ) {
62+ this . SerialNumber = line . replace ( / ^ ( S N | S e r i a l N u m b e r ) : / , '' ) . trim ( ) ;
63+ } else if ( line . startsWith ( 'Tool Count:' ) || line . startsWith ( 'Tool count:' ) ) {
64+ this . ToolCount = line . split ( ':' ) [ 1 ] ?. trim ( ) ?? '' ;
65+ } else if ( line . startsWith ( 'Mac Address:' ) ) {
66+ this . MacAddress = line . replace ( 'Mac Address:' , '' ) . trim ( ) ;
67+ } else {
68+ const volumeMatch = line . match ( / X : \s * \d + \s + Y : \s * \d + \s + Z : \s * \d + / i) ;
69+ if ( volumeMatch ) {
70+ this . Dimensions = line ;
71+ }
72+ }
6273 }
63- this . TypeName = name ;
6474
65- const nick = getRight ( data [ 2 ] ) ; // Expected: "Machine Name: MyPrinter"
66- if ( nick === null ) {
67- console . log ( 'PrinterInfo replay has null Machine Name' ) ;
75+ if ( ! this . TypeName ) {
76+ console . log ( 'PrinterInfo replay has null Machine Type' ) ;
6877 return null ;
6978 }
70- this . Name = nick ;
71-
72- const fw = getRight ( data [ 3 ] ) ; // Expected: "Firmware: V1.2.3"
73- if ( fw === null ) {
79+ if ( ! this . FirmwareVersion ) {
7480 console . log ( 'PrinterInfo replay has null firmware version' ) ;
7581 return null ;
7682 }
77- this . FirmwareVersion = fw ;
78-
79- const sn = getRight ( data [ 4 ] ) ; // Expected: "SN: SN12345"
80- if ( sn === null ) {
81- console . log ( 'PrinterInfo replay has null serial number' ) ;
82- return null ;
83- }
84- this . SerialNumber = sn ;
8583
86- this . Dimensions = data [ 5 ] . trim ( ) ; // Expected: "X:220 Y:220 Z:220" (or similar, directly)
87-
88- const tcs = getRight ( data [ 6 ] ) ; // Expected: "Tool count: 1"
89- if ( tcs === null ) {
90- console . log ( 'PrinterInfo replay has null tool count' ) ;
91- return null ;
92- }
93- this . ToolCount = tcs ;
94-
95- this . MacAddress = data [ 7 ] . replace ( 'Mac Address:' , '' ) . trim ( ) ; // Expected: "Mac Address: XX:XX:XX:XX:XX:XX"
9684 return this ;
9785 } catch ( _error ) {
9886 console . log ( 'Error creating PrinterInfo instance from replay' ) ;
@@ -130,17 +118,3 @@ export class PrinterInfo {
130118 }
131119}
132120
133- /**
134- * Helper function to extract the value part of a "Key: Value" string.
135- * It splits the input string by the first colon and returns the trimmed value part.
136- * @param rpData The input string (e.g., "Machine Type: Adventurer 5M Pro").
137- * @returns The extracted value string (e.g., "Adventurer 5M Pro"), or null if parsing fails.
138- * @private
139- */
140- function getRight ( rpData : string ) : string | null {
141- try {
142- return rpData . split ( ':' ) [ 1 ] . trim ( ) ;
143- } catch {
144- return null ;
145- }
146- }
0 commit comments