11import { Converters } from "./converters" ;
2+ import { DataField } from "./data-field" ;
23
3- export const functionCodes : { [ code : number ] : string } = {
4- 0x01 : 'Read Coils' ,
5- 0x02 : 'Read Discrete Inputs' ,
6- 0x03 : 'Read Holding Registers' ,
7- 0x04 : 'Read Input Registers' ,
8- 0x05 : 'Write Single Coil' ,
9- 0x06 : 'Write Single Register' ,
10- 0x07 : 'Read Exceptions Status' ,
11- 0x08 : 'Diagnostic Test' ,
12- 0x0f : 'Write Multiple Coils' ,
13- 0x10 : 'Write Multiple Registers' ,
14- 0x11 : 'Identify Device Server' ,
15- } ;
4+ interface FunctionCodeDetails {
5+ readonly code : number ;
6+ readonly description : string ;
7+ readonly masterRequestStrategy ?: DataField ;
8+ readonly slaveResponseStrategy ?: DataField ;
9+ }
1610
17- export const errorCodes : { [ code : number ] : string } = {
18- 0x81 : 'Illegal Function' ,
19- 0x82 : 'Illegal Data Address' ,
20- 0x83 : 'Illegal Data Value' ,
21- 0x84 : 'Server Device Failure' ,
22- 0x85 : 'Acknowledge' ,
23- 0x86 : 'Server Device Busy' ,
24- 0x87 : 'Negative Acknowledge' ,
25- 0x88 : 'Memory Parity Error' ,
26- 0x90 : 'Gateway Path Unavailable' ,
27- 0x91 : 'Gateway Target Device Failed to Respond' ,
28- } ;
11+ const allFunctionCodeDetails : ReadonlySet < FunctionCodeDetails > = new Set < FunctionCodeDetails > ( [
12+ { code : 0x01 , description : 'Read Coils' } ,
13+ { code : 0x02 , description : 'Read Discrete Inputs' } ,
14+ { code : 0x03 , description : 'Read Holding Registers' } ,
15+ { code : 0x04 , description : 'Read Input Registers' } ,
16+ { code : 0x05 , description : 'Write Single Coil' } ,
17+ { code : 0x06 , description : 'Write Single Register' } ,
18+ { code : 0x07 , description : 'Read Exceptions Status' } ,
19+ { code : 0x08 , description : 'Diagnostic Test' } ,
20+ { code : 0x0f , description : 'Write Multiple Coils' } ,
21+ { code : 0x10 , description : 'Write Multiple Registers' } ,
22+ { code : 0x11 , description : 'Identify Device Server' } ,
23+ { code : 0x81 , description : 'Illegal Function' } ,
24+ { code : 0x82 , description : 'Illegal Data Address' } ,
25+ { code : 0x83 , description : 'Illegal Data Value' } ,
26+ { code : 0x84 , description : 'Server Device Failure' } ,
27+ { code : 0x85 , description : 'Acknowledge' } ,
28+ { code : 0x86 , description : 'Server Device Busy' } ,
29+ { code : 0x87 , description : 'Negative Acknowledge' } ,
30+ { code : 0x88 , description : 'Memory Parity Error' } ,
31+ { code : 0x90 , description : 'Gateway Path Unavailable' } ,
32+ { code : 0x91 , description : 'Gateway Target Device Failed to Respond' } ,
33+ ] ) ;
2934
35+ export class FunctionCodes {
36+ static descriptions : ReadonlyMap < number , string > = new Map < number , string > ( [ ...allFunctionCodeDetails ] . map ( ( it ) => [ it . code , it . description ] ) ) ;
3037
31- export const getFunctionCodeDescription = ( code : number ) : string => {
32- const description = functionCodes [ code ] ?? errorCodes [ code ] ;
33- if ( description ) {
34- return `0x${ Converters . byteToHex ( code ) } ${ description } ` ;
38+ static getDescription ( code : number | undefined ) : string {
39+ if ( code === undefined ) {
40+ return '' ;
41+ }
42+ const description = this . descriptions . get ( code ) ;
43+ if ( description ) {
44+ return this . _getDescription ( code , description ) ;
45+ }
46+ return this . _getDescription ( code , '<UNKNOWN>' ) ;
3547 }
36- return `0x${ Converters . byteToHex ( code ) } UNKNOWN` ;
37- }
48+
49+ private static _getDescription ( code : number , description : string ) : string {
50+ return `${ code } = 0x${ Converters . byteToHex ( code ) } => ${ description } ${ this . isError ( code ) ? '(ERROR)' : '' } ` ;
51+ }
52+
53+ static isError ( code : number ) : boolean {
54+ return ! ! ( code & 0x80 ) ;
55+ }
56+ }
0 commit comments