Skip to content

Commit 5431874

Browse files
committed
Restructore modes
1 parent 68b4212 commit 5431874

File tree

6 files changed

+147
-139
lines changed

6 files changed

+147
-139
lines changed

src/int.spec.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {Converters} from "./converters";
2-
import {AsciiModeStrategy, RtuModeStrategy} from "./mode";
2+
import {RtuModeStrategy} from "./mode/rtu-mode-strategy";
3+
import {AsciiModeStrategy} from "./mode/ascii-mode-strategy";
34

45
export const intTest = (): void => {
56
new RtuModeStrategy().receive(new Uint8Array([

src/main.ts

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

3-
import {AsciiModeStrategy, ModeStrategy, RtuModeStrategy} from "./mode";
3+
import {ModeStrategy} from "./mode/mode-startegy";
44
import {clearSniffingTable, Dom, downloadAllSniffedEntries, insertFrameRow} from "./dom";
55
import {Frame} from "./frame";
66
import {FunctionCodes} from "./function-codes";
7+
import {RtuModeStrategy} from "./mode/rtu-mode-strategy";
8+
import {AsciiModeStrategy} from "./mode/ascii-mode-strategy";
79

810
const serial: Serial = navigator.serial;
911
if (!serial) {

src/mode.ts

Lines changed: 0 additions & 137 deletions
This file was deleted.

src/mode/ascii-mode-strategy.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import {Frame} from "../frame";
2+
import {Converters} from "../converters";
3+
import {ModeStrategy, reportFrame} from "./mode-startegy";
4+
5+
export class AsciiModeStrategy extends ModeStrategy {
6+
frameChars: number[] = [];
7+
frameBytes: number[] = [];
8+
currentLrc: number = 0x00;
9+
10+
receive(data: Uint8Array): void {
11+
data.forEach((it) => this.frameChars.push(it));
12+
while (this.frameChars.length >= 2) {
13+
const char: number = this.frameChars.shift()!;
14+
if (char === 0x3A) {
15+
this.resetFrame();
16+
} else {
17+
const char2: number = this.frameChars.shift()!;
18+
if (char2 === 0x3A) {
19+
this.resetFrame();
20+
} else if (char === 0x0D && char2 === 0x0A) {
21+
this.frameBytes.pop();
22+
if (!isNaN(this.currentLrc) && (this.currentLrc & 0xff) === 0) {
23+
reportFrame(new Frame(this.frameBytes, ''));
24+
} else {
25+
reportFrame(new Frame(this.frameBytes, 'error'));
26+
}
27+
this.frameBytes = [];
28+
this.currentLrc = 0x00;
29+
} else {
30+
const byte = parseInt(String.fromCharCode(char, char2), 16);
31+
this.frameBytes.push(byte);
32+
this.updateLrc(byte);
33+
}
34+
}
35+
}
36+
}
37+
38+
send(bytes: number[]): Uint8Array {
39+
let lrc = 0;
40+
bytes.forEach((byte) => lrc += byte);
41+
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;
46+
}
47+
48+
private resetFrame(): void {
49+
if (this.frameBytes.length) {
50+
reportFrame(new Frame(this.frameBytes, 'error'));
51+
this.frameBytes = [];
52+
this.currentLrc = 0x00;
53+
}
54+
}
55+
56+
private updateLrc(byte: number): void {
57+
this.currentLrc += byte;
58+
}
59+
}

src/mode/mode-startegy.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import {insertFrameRow} from "../dom";
2+
import {Frame} from "../frame";
3+
4+
export const reportFrame = (frame: Frame): void => {
5+
insertFrameRow(frame);
6+
};
7+
8+
export abstract class ModeStrategy {
9+
abstract receive(data: Uint8Array): void;
10+
11+
abstract send(bytes: number[]): Uint8Array;
12+
}
13+

src/mode/rtu-mode-strategy.ts

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import {Frame} from "../frame";
2+
import {ModeStrategy, reportFrame} from "./mode-startegy";
3+
4+
class RtuCrc {
5+
crc: number = 0xFFFF;
6+
7+
updateCrc(byte: number): boolean {
8+
this.crc ^= byte;
9+
for (let i = 0; i < 8; ++i) {
10+
const xor = this.crc & 1;
11+
this.crc >>= 1;
12+
if (xor) {
13+
this.crc ^= 0xA001;
14+
}
15+
}
16+
return this.crc === 0;
17+
}
18+
}
19+
20+
class RtuCurrentByte extends RtuCrc {
21+
constructor(public readonly byte: number) {
22+
super();
23+
}
24+
}
25+
26+
export class RtuModeStrategy extends ModeStrategy {
27+
history: RtuCurrentByte[] = [];
28+
timeoutHandler?: any;
29+
30+
receive(data: Uint8Array): void {
31+
if (this.timeoutHandler) {
32+
clearTimeout(this.timeoutHandler!);
33+
}
34+
this.timeoutHandler = setTimeout(() => this.resetFrame(), 200);
35+
data.forEach((byte) => {
36+
this.history.push(new RtuCurrentByte(byte));
37+
for (let i = 0; i < this.history.length; ++i) {
38+
if (this.history[i].updateCrc(byte)) {
39+
const bytes = this.history.map((it) => it.byte);
40+
if (i) {
41+
reportFrame(new Frame(bytes.slice(0, i), 'error'));
42+
}
43+
const validFrame = new Frame(bytes.slice(i, -2), '');
44+
reportFrame(validFrame);
45+
this.history = [];
46+
clearTimeout(this.timeoutHandler!);
47+
break;
48+
}
49+
}
50+
if (this.history.length > 2300) {
51+
reportFrame(new Frame(this.history.splice(0, 200).map((it) => it.byte), 'error'))
52+
}
53+
});
54+
}
55+
56+
send(bytes: number[]): Uint8Array {
57+
const rtuCrc = new RtuCrc();
58+
bytes.forEach((byte) => rtuCrc.updateCrc(byte));
59+
const firstCrcByte = rtuCrc.crc & 0xff;
60+
rtuCrc.updateCrc(firstCrcByte);
61+
const result = new Uint8Array([...bytes, firstCrcByte, rtuCrc.crc]);
62+
//this.receive(result);
63+
return result;
64+
}
65+
66+
private resetFrame(): void {
67+
reportFrame(new Frame(this.history.map((it) => it.byte), 'error'));
68+
this.history = [];
69+
}
70+
}

0 commit comments

Comments
 (0)