Skip to content

Commit cf4726b

Browse files
committed
Refactor modes, to make it independent of the rest of the code base
1 parent abcf794 commit cf4726b

File tree

6 files changed

+32
-34
lines changed

6 files changed

+32
-34
lines changed

src/frame.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,6 @@ export class Frame {
4646
];
4747
}
4848

49-
protected getError(e: any): string {
50-
return e.message;
51-
}
52-
5349
private getDataAsText(): string {
5450
if (this.type === 'error') {
5551
return `Invalid frame: 0x${this.hexData}`;

src/int.spec.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import {RtuModeStrategy} from "./mode/rtu-mode-strategy";
33
import {AsciiModeStrategy} from "./mode/ascii-mode-strategy";
44

55
export const intTest = (): void => {
6-
new RtuModeStrategy(300).receive(new Uint8Array([
6+
new RtuModeStrategy(() => {
7+
}, 300).receive(new Uint8Array([
78
0x11, 0x22, 0x33, 0x44, 0x55, // some mess
89
0x04, 0x01, 0x00, 0x0A, 0x00, 0x0D, 0xdd, 0x98, // valid: address & quantity
910
0xFF, 0xFF, // valid CRC but invalid frame
@@ -13,7 +14,8 @@ export const intTest = (): void => {
1314
0x01, 0x10, 0x0F, 0xA3, 0x00, 0x02, 0x04, 0x00, 0x14, 0x07, 0xD0, 0xBB, 0x9A, // valid: expected uint16 20, 2000
1415
]));
1516

16-
new AsciiModeStrategy().receive(Converters.textAsUInt8Array(
17+
new AsciiModeStrategy(() => {
18+
},).receive(Converters.textAsUInt8Array(
1719
'&*^&^%^%$*&&%%$#' + // simply totally invalid frame
1820
':0401000A000DE4\r\n' + // valid: address & quantity
1921
'xyz!@=$%#$;' + // simply totally invalid frame

src/main.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/// <reference types="w3c-web-serial" />
22

3-
import {ModeStrategy} from "./mode/mode-startegy";
3+
import {ModeStrategy, ReportType} from "./mode/mode-startegy";
44
import {clearSniffingTable, Dom, downloadAllSniffedEntries, insertFrameRow} from "./dom";
55
import {Frame} from "./frame";
66
import {FunctionCodes} from "./function-codes";
@@ -16,11 +16,15 @@ if (!serial) {
1616
Dom.clearSnifferButton.addEventListener('click', () => clearSniffingTable());
1717
Dom.downloadSnifferButton.addEventListener('click', () => downloadAllSniffedEntries());
1818

19+
const getModeReport = (bytes: number[], type: ReportType): void =>
20+
insertFrameRow(new Frame(bytes, type));
21+
22+
1923
Dom.serialForm.submit = (formData) => {
2024
formData.baudRate = +formData.baudRate;
2125
formData.stopBits = formData.parity !== 'none' ? 1 : 2;
2226
formData.dataBits = formData.mode === 'ASCII' ? 7 : 8;
23-
start(formData, formData.mode === 'ASCII' ? new AsciiModeStrategy() : new RtuModeStrategy(formData.baudRate));
27+
start(formData, formData.mode === 'ASCII' ? new AsciiModeStrategy(getModeReport) : new RtuModeStrategy(getModeReport, formData.baudRate));
2428
};
2529

2630
let send: ((bytest: number[]) => Promise<void>) | undefined = undefined;

src/mode/ascii-mode-strategy.ts

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1-
import {Frame} from "../frame";
21
import {Converters} from "../converters";
3-
import {ModeStrategy, reportFrame} from "./mode-startegy";
2+
import {ModeStrategy, ReportType} from "./mode-startegy";
43

54
export class AsciiModeStrategy implements ModeStrategy {
65
frameChars: number[] = [];
76
frameBytes: number[] = [];
87
currentLrc: number = 0x00;
98

9+
constructor(readonly report: (bytes: number[], type: ReportType) => void) {
10+
}
11+
1012
receive(data: Uint8Array): void {
1113
data.forEach((it) => this.frameChars.push(it));
1214
while (this.frameChars.length >= 2) {
@@ -20,9 +22,9 @@ export class AsciiModeStrategy implements ModeStrategy {
2022
} else if (char === 0x0D && char2 === 0x0A) {
2123
this.frameBytes.pop();
2224
if (!isNaN(this.currentLrc) && (this.currentLrc & 0xff) === 0) {
23-
reportFrame(new Frame(this.frameBytes, ''));
25+
this.report(this.frameBytes, ReportType.valid);
2426
} else {
25-
reportFrame(new Frame(this.frameBytes, 'error'));
27+
this.report(this.frameBytes, ReportType.errored);
2628
}
2729
this.frameBytes = [];
2830
this.currentLrc = 0x00;
@@ -39,15 +41,12 @@ export class AsciiModeStrategy implements ModeStrategy {
3941
let lrc = 0;
4042
bytes.forEach((byte) => lrc += byte);
4143
const line = `:${Converters.bytesAsHex(bytes)}${Converters.byteToHex(-lrc & 0xff)}\r\n`;
42-
console.log(bytes, line);
43-
const result = Converters.textAsUInt8Array(line);
44-
//this.receive(result);
45-
return result;
44+
return Converters.textAsUInt8Array(line);
4645
}
4746

4847
private resetFrame(): void {
4948
if (this.frameBytes.length) {
50-
reportFrame(new Frame(this.frameBytes, 'error'));
49+
this.report(this.frameBytes, ReportType.errored);
5150
this.frameBytes = [];
5251
this.currentLrc = 0x00;
5352
}

src/mode/mode-startegy.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
1-
import {insertFrameRow} from "../dom";
2-
import {Frame} from "../frame";
3-
4-
export const reportFrame = (frame: Frame): void => {
5-
insertFrameRow(frame);
6-
};
1+
export enum ReportType {
2+
valid = '',
3+
errored = 'error',
4+
sent = 'send',
5+
}
76

87
export interface ModeStrategy {
98
receive(data: Uint8Array): void;
109

1110
send(bytes: number[]): Uint8Array;
11+
12+
report(bytes: number[], type: ReportType): void;
1213
}
1314

src/mode/rtu-mode-strategy.ts

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import {Frame} from "../frame";
2-
import {ModeStrategy, reportFrame} from "./mode-startegy";
1+
import {ModeStrategy, ReportType} from "./mode-startegy";
32

43
class RtuCrc {
54
crc: number = 0xFFFF;
@@ -28,7 +27,7 @@ export class RtuModeStrategy implements ModeStrategy {
2827
protected timeoutHandler?: any;
2928
protected timeoutMs: number;
3029

31-
constructor(baudRate: number) {
30+
constructor(readonly report: (bytes: number[], type: ReportType) => void, baudRate: number) {
3231
this.timeoutMs = 1 + Math.ceil(50 * 1000 / baudRate);
3332
}
3433

@@ -43,17 +42,16 @@ export class RtuModeStrategy implements ModeStrategy {
4342
if (this.history[i].updateCrc(byte)) {
4443
const bytes = this.history.map((it) => it.byte);
4544
if (i) {
46-
reportFrame(new Frame(bytes.slice(0, i), 'error'));
45+
this.report(bytes.slice(0, i), ReportType.errored);
4746
}
48-
const validFrame = new Frame(bytes.slice(i, -2), '');
49-
reportFrame(validFrame);
47+
this.report(bytes.slice(i, -2), ReportType.valid);
5048
this.history = [];
5149
clearTimeout(this.timeoutHandler!);
5250
break;
5351
}
5452
}
5553
if (this.history.length > 2300) {
56-
reportFrame(new Frame(this.history.splice(0, 200).map((it) => it.byte), 'error'))
54+
this.report(this.history.splice(0, 200).map((it) => it.byte), ReportType.errored);
5755
}
5856
});
5957
}
@@ -63,13 +61,11 @@ export class RtuModeStrategy implements ModeStrategy {
6361
bytes.forEach((byte) => rtuCrc.updateCrc(byte));
6462
const firstCrcByte = rtuCrc.crc & 0xff;
6563
rtuCrc.updateCrc(firstCrcByte);
66-
const result = new Uint8Array([...bytes, firstCrcByte, rtuCrc.crc]);
67-
//this.receive(result);
68-
return result;
64+
return new Uint8Array([...bytes, firstCrcByte, rtuCrc.crc]);
6965
}
7066

7167
private resetFrame(): void {
72-
reportFrame(new Frame(this.history.map((it) => it.byte), 'error'));
68+
this.report(this.history.map((it) => it.byte), ReportType.errored);
7369
this.history = [];
7470
}
7571
}

0 commit comments

Comments
 (0)