jooby-codec 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/dist/BinaryBuffer.d.ts +44 -0
  2. package/dist/BinaryBuffer.js +128 -0
  3. package/dist/BinaryBuffer.js.map +1 -0
  4. package/dist/Command.d.ts +42 -0
  5. package/dist/Command.js +80 -0
  6. package/dist/Command.js.map +1 -0
  7. package/dist/CommandBinaryBuffer.d.ts +45 -0
  8. package/dist/CommandBinaryBuffer.js +135 -0
  9. package/dist/CommandBinaryBuffer.js.map +1 -0
  10. package/dist/commands/downlink/CorrectTime2000.d.ts +49 -0
  11. package/dist/commands/downlink/CorrectTime2000.js +61 -0
  12. package/dist/commands/downlink/CorrectTime2000.js.map +1 -0
  13. package/dist/commands/downlink/SetTime2000.d.ts +45 -0
  14. package/dist/commands/downlink/SetTime2000.js +60 -0
  15. package/dist/commands/downlink/SetTime2000.js.map +1 -0
  16. package/dist/commands/downlink/index.d.ts +7 -0
  17. package/dist/commands/downlink/index.js +8 -0
  18. package/dist/commands/downlink/index.js.map +1 -0
  19. package/dist/commands/index.d.ts +7 -0
  20. package/dist/commands/index.js +8 -0
  21. package/dist/commands/index.js.map +1 -0
  22. package/dist/commands/uplink/CorrectTime2000.d.ts +37 -0
  23. package/dist/commands/uplink/CorrectTime2000.js +53 -0
  24. package/dist/commands/uplink/CorrectTime2000.js.map +1 -0
  25. package/dist/commands/uplink/DataDayMul.d.ts +20 -0
  26. package/dist/commands/uplink/DataDayMul.js +41 -0
  27. package/dist/commands/uplink/DataDayMul.js.map +1 -0
  28. package/dist/commands/uplink/DataHourMul.d.ts +11 -0
  29. package/dist/commands/uplink/DataHourMul.js +77 -0
  30. package/dist/commands/uplink/DataHourMul.js.map +1 -0
  31. package/dist/commands/uplink/ExAbsDayMul.d.ts +11 -0
  32. package/dist/commands/uplink/ExAbsDayMul.js +60 -0
  33. package/dist/commands/uplink/ExAbsDayMul.js.map +1 -0
  34. package/dist/commands/uplink/ExAbsHourMul.d.ts +11 -0
  35. package/dist/commands/uplink/ExAbsHourMul.js +92 -0
  36. package/dist/commands/uplink/ExAbsHourMul.js.map +1 -0
  37. package/dist/commands/uplink/GetCurrentMul.d.ts +24 -0
  38. package/dist/commands/uplink/GetCurrentMul.js +35 -0
  39. package/dist/commands/uplink/GetCurrentMul.js.map +1 -0
  40. package/dist/commands/uplink/NewEvent.d.ts +18 -0
  41. package/dist/commands/uplink/NewEvent.js +101 -0
  42. package/dist/commands/uplink/NewEvent.js.map +1 -0
  43. package/dist/commands/uplink/SetTime2000.d.ts +37 -0
  44. package/dist/commands/uplink/SetTime2000.js +53 -0
  45. package/dist/commands/uplink/SetTime2000.js.map +1 -0
  46. package/dist/commands/uplink/Time2000.d.ts +41 -0
  47. package/dist/commands/uplink/Time2000.js +56 -0
  48. package/dist/commands/uplink/Time2000.js.map +1 -0
  49. package/dist/commands/uplink/index.d.ts +13 -0
  50. package/dist/commands/uplink/index.js +14 -0
  51. package/dist/commands/uplink/index.js.map +1 -0
  52. package/dist/constants/events.d.ts +16 -0
  53. package/dist/constants/events.js +17 -0
  54. package/dist/constants/events.js.map +1 -0
  55. package/dist/constants/general.d.ts +1 -0
  56. package/dist/constants/general.js +2 -0
  57. package/dist/constants/general.js.map +1 -0
  58. package/dist/constants/index.d.ts +1 -0
  59. package/dist/constants/index.js +2 -0
  60. package/dist/constants/index.js.map +1 -0
  61. package/dist/index.d.ts +4 -0
  62. package/dist/index.js +5 -0
  63. package/dist/index.js.map +1 -0
  64. package/dist/utils/getBitArrayFromNumber.d.ts +14 -0
  65. package/dist/utils/getBitArrayFromNumber.js +15 -0
  66. package/dist/utils/getBitArrayFromNumber.js.map +1 -0
  67. package/dist/utils/getBytesFromHex.d.ts +11 -0
  68. package/dist/utils/getBytesFromHex.js +23 -0
  69. package/dist/utils/getBytesFromHex.js.map +1 -0
  70. package/dist/utils/getHexFromBytes.d.ts +27 -0
  71. package/dist/utils/getHexFromBytes.js +22 -0
  72. package/dist/utils/getHexFromBytes.js.map +1 -0
  73. package/dist/utils/getIntFromBitString.d.ts +6 -0
  74. package/dist/utils/getIntFromBitString.js +6 -0
  75. package/dist/utils/getIntFromBitString.js.map +1 -0
  76. package/dist/utils/header.d.ts +13 -0
  77. package/dist/utils/header.js +62 -0
  78. package/dist/utils/header.js.map +1 -0
  79. package/dist/utils/index.d.ts +2 -0
  80. package/dist/utils/index.js +3 -0
  81. package/dist/utils/index.js.map +1 -0
  82. package/dist/utils/message.d.ts +27 -0
  83. package/dist/utils/message.js +101 -0
  84. package/dist/utils/message.js.map +1 -0
  85. package/dist/utils/roundNumber.d.ts +2 -0
  86. package/dist/utils/roundNumber.js +5 -0
  87. package/dist/utils/roundNumber.js.map +1 -0
  88. package/dist/utils/time.d.ts +14 -0
  89. package/dist/utils/time.js +17 -0
  90. package/dist/utils/time.js.map +1 -0
  91. package/package.json +78 -0
  92. package/readme.md +145 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"header.js","sourceRoot":"","sources":["../../src/utils/header.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,MAAM,sBAAsB,CAAC;AACnD,OAAO,eAAoC,MAAM,sBAAsB,CAAC;AAGxE,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAC9B,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAG9B,MAAM,CAAC,MAAM,SAAS,GAAG,CAAE,IAAgB,EAAG,EAAE;IAC5C,IAAK,IAAI,CAAC,MAAM,KAAK,CAAC,EAAG;QACrB,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;KAC1C;IAED,MAAM,MAAM,GAAG;QACX,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,gBAAgB;QACrC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,gBAAgB;KACxC,CAAC;IAEF,IAAK,MAAM,CAAC,SAAS,KAAK,CAAC,EAAG;QAC1B,eAAe;QACf,OAAO;YACH,UAAU,EAAE,CAAC;YACb,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC;YACxC,WAAW,EAAE,MAAM,CAAC,SAAS;SAChC,CAAC;KACL;IAED,IAAK,MAAM,CAAC,SAAS,KAAK,gBAAgB,EAAG;QACzC,gBAAgB;QAChB,IAAK,IAAI,CAAC,MAAM,GAAG,CAAC,EAAG;YACnB,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;SAC1C;QACD,OAAO;YACH,UAAU,EAAE,CAAC;YACb,SAAS,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,gBAAgB;YAC5C,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC;SACvB,CAAC;KACL;IAED,IAAK,IAAI,CAAC,MAAM,GAAG,CAAC,EAAG;QACnB,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;KAC1C;IAED,OAAO;QACH,UAAU,EAAE,CAAC;QACb,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC;KACvB,CAAC;AACN,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAG,CAAE,IAAY,EAAG,EAAE,CAAC,SAAS,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC;AAE5E,MAAM,CAAC,MAAM,OAAO,GAAG,CAAE,SAAiB,EAAE,WAAmB,EAAe,EAAE;IAC5E,IAAK,CAAC,SAAS,GAAG,gBAAgB,CAAC,KAAK,CAAC,EAAG;QACxC,IAAK,WAAW,GAAG,gBAAgB,EAAG;YAClC,MAAM,IAAI,KAAK,CAAC,8BAA8B,SAAS,WAAW,WAAW,GAAG,CAAC,CAAC;SACrF;QAED,OAAO,IAAI,UAAU,CAAC,CAAC,SAAS,GAAG,WAAW,CAAC,CAAC,CAAC;KACpD;IAED,IAAK,SAAS,GAAG,gBAAgB,EAAG;QAChC,OAAO,IAAI,UAAU,CAAC;YAClB,gBAAgB;YAChB,CAAC,SAAS,IAAI,CAAC,CAAC;YAChB,WAAW;SACd,CAAC,CAAC;KACN;IAED,OAAO,IAAI,UAAU,CAAC;QAClB,SAAS;QACT,WAAW;KACd,CAAC,CAAC;AACP,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,KAAK,GAAG,CAAE,SAAiB,EAAE,WAAmB,EAAE,UAA6B,EAAE,EAAW,EAAE,CAAC,CACxG,eAAe,CAAC,OAAO,CAAC,SAAS,EAAE,WAAW,CAAC,EAAE,OAAO,CAAC,CAC5D,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { default as getBytesFromHex } from './getBytesFromHex.js';
2
+ export { default as getHexFromBytes, IHexFormatOptions } from './getHexFromBytes.js';
@@ -0,0 +1,3 @@
1
+ export { default as getBytesFromHex } from './getBytesFromHex.js';
2
+ export { default as getHexFromBytes } from './getHexFromBytes.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,IAAI,eAAe,EAAC,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAC,OAAO,IAAI,eAAe,EAAoB,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,27 @@
1
+ import Command from '../Command.js';
2
+ import { IHexFormatOptions } from './getHexFromBytes.js';
3
+ interface IMessageCommand {
4
+ /** command source binary data */
5
+ data: {
6
+ header: Uint8Array;
7
+ body: Uint8Array;
8
+ };
9
+ /** specific command instance */
10
+ command: Command;
11
+ }
12
+ interface IMessage {
13
+ commands: Array<IMessageCommand>;
14
+ lrc: {
15
+ expected: number;
16
+ actual: number;
17
+ };
18
+ isValid: boolean;
19
+ }
20
+ export declare const TYPE_AUTO = 0;
21
+ export declare const TYPE_DOWNLINK = 1;
22
+ export declare const TYPE_UPLINK = 2;
23
+ export declare const fromBytes: (data: Uint8Array, direction?: number) => IMessage;
24
+ export declare const fromHex: (data: string, direction?: number) => IMessage;
25
+ export declare const toBytes: (commands: Array<Command>) => Uint8Array;
26
+ export declare const toHex: (commands: Array<Command>, options?: IHexFormatOptions) => string;
27
+ export {};
@@ -0,0 +1,101 @@
1
+ import * as downlinkCommands from '../commands/downlink/index.js';
2
+ import * as uplinkCommands from '../commands/uplink/index.js';
3
+ import * as header from './header.js';
4
+ import getBytesFromHex from './getBytesFromHex.js';
5
+ import getHexFromBytes from './getHexFromBytes.js';
6
+ export const TYPE_AUTO = 0;
7
+ export const TYPE_DOWNLINK = 1;
8
+ export const TYPE_UPLINK = 2;
9
+ const HEADER_MAX_SIZE = 3;
10
+ // convert export namespace to dictionary {commandId: commandConstructor}
11
+ const downlinkCommandsById = Object.fromEntries(Object.values(downlinkCommands).map(item => [item.id, item]));
12
+ const uplinkCommandsById = Object.fromEntries(Object.values(uplinkCommands).map(item => [item.id, item]));
13
+ /**
14
+ * Calculate LRC
15
+ *
16
+ * @param data - byte array
17
+ *
18
+ * @return LRC
19
+ */
20
+ const calculateLrc = (data, initialLrc = 0x55) => {
21
+ let lrc = initialLrc;
22
+ data.forEach(item => {
23
+ lrc ^= item;
24
+ });
25
+ return lrc;
26
+ };
27
+ const getCommand = (id, data, direction = TYPE_AUTO) => {
28
+ // given direction
29
+ if (direction === TYPE_DOWNLINK || direction === TYPE_UPLINK) {
30
+ const commandsById = direction === TYPE_DOWNLINK ? downlinkCommandsById : uplinkCommandsById;
31
+ const command = commandsById[id];
32
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
33
+ if (!command) {
34
+ throw new Error(`Unsupported command with id: ${id}.`);
35
+ }
36
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
37
+ return command.fromBytes(data);
38
+ }
39
+ // auto direction
40
+ // try downlink
41
+ try {
42
+ const command = downlinkCommandsById[id];
43
+ // console.log('command downlink:', command);
44
+ // console.log('downlinkCommandsById:', downlinkCommandsById);
45
+ // console.log('id:', id);
46
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
47
+ return command.fromBytes(data);
48
+ }
49
+ catch {
50
+ // try uplink
51
+ const command = uplinkCommandsById[id];
52
+ //console.log('command uplink:', command);
53
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
54
+ return command.fromBytes(data);
55
+ }
56
+ };
57
+ export const fromBytes = (data, direction = TYPE_AUTO) => {
58
+ const commandsData = data.slice(0, -1);
59
+ const expectedLrc = data.at(-1) ?? 0;
60
+ const actualLrc = calculateLrc(commandsData);
61
+ const commands = [];
62
+ const result = {
63
+ commands,
64
+ lrc: { expected: 0, actual: 0 },
65
+ isValid: false
66
+ };
67
+ let position = 0;
68
+ do {
69
+ const headerInfo = header.fromBytes(commandsData.slice(position, position + HEADER_MAX_SIZE));
70
+ const headerData = commandsData.slice(position, position + headerInfo.headerSize);
71
+ const bodyData = commandsData.slice(position + headerInfo.headerSize, position + headerInfo.headerSize + headerInfo.commandSize);
72
+ commands.push({
73
+ data: { header: headerData, body: bodyData },
74
+ command: getCommand(headerInfo.commandId, bodyData, direction)
75
+ });
76
+ // shift
77
+ position = position + headerInfo.headerSize + headerInfo.commandSize;
78
+ } while (position < commandsData.length);
79
+ result.lrc.actual = actualLrc;
80
+ result.lrc.expected = expectedLrc;
81
+ result.isValid = expectedLrc === actualLrc;
82
+ return result;
83
+ };
84
+ export const fromHex = (data, direction = TYPE_AUTO) => fromBytes(getBytesFromHex(data), direction);
85
+ export const toBytes = (commands) => {
86
+ const arrays = commands.map(command => command.toBytes());
87
+ const totalLength = arrays.reduce((accumulator, item) => (accumulator + item.length), 0);
88
+ // 1 additional byte at the end is for LRC
89
+ const result = new Uint8Array(totalLength + 1);
90
+ let offset = 0;
91
+ // fill result with all chunks
92
+ arrays.forEach(item => {
93
+ result.set(item, offset);
94
+ offset += item.length;
95
+ });
96
+ // set last byte to LRC
97
+ result[result.length - 1] = calculateLrc(result.slice(0, result.length - 1));
98
+ return result;
99
+ };
100
+ export const toHex = (commands, options = {}) => getHexFromBytes(toBytes(commands), options);
101
+ //# sourceMappingURL=message.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message.js","sourceRoot":"","sources":["../../src/utils/message.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ declare const _default: (value: number, decimalPlaces?: number) => number;
2
+ export default _default;
@@ -0,0 +1,5 @@
1
+ export default (value, decimalPlaces = 4) => {
2
+ const places = 10 ** decimalPlaces;
3
+ return Math.round((value * places) * (1 + Number.EPSILON)) / places;
4
+ };
5
+ //# sourceMappingURL=roundNumber.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"roundNumber.js","sourceRoot":"","sources":["../../src/utils/roundNumber.ts"],"names":[],"mappings":"AAAA,eAAe,CAAE,KAAa,EAAE,aAAa,GAAG,CAAC,EAAG,EAAE;IAClD,MAAM,MAAM,GAAG,EAAE,IAAI,aAAa,CAAC;IAEnC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,MAAM,CAAC;AACxE,CAAC,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Get date object from UTC seconds since 2000 year.
3
+ *
4
+ * @param time - seconds since 2000 year
5
+ * @returns Date object instance
6
+ */
7
+ export declare const getDateFromSeconds: (time: number) => Date;
8
+ /**
9
+ * Get UTC seconds since 2000 year from Date object.
10
+ *
11
+ * @param date - Date object
12
+ * @returns seconds since 2000 year
13
+ */
14
+ export declare const getSecondsFromDate: (date: Date) => number;
@@ -0,0 +1,17 @@
1
+ const INITIAL_YEAR_TIMESTAMP = 946684800000;
2
+ const MILLISECONDS_IN_SECONDS = 1000;
3
+ /**
4
+ * Get date object from UTC seconds since 2000 year.
5
+ *
6
+ * @param time - seconds since 2000 year
7
+ * @returns Date object instance
8
+ */
9
+ export const getDateFromSeconds = (time) => new Date(INITIAL_YEAR_TIMESTAMP + (time * MILLISECONDS_IN_SECONDS));
10
+ /**
11
+ * Get UTC seconds since 2000 year from Date object.
12
+ *
13
+ * @param date - Date object
14
+ * @returns seconds since 2000 year
15
+ */
16
+ export const getSecondsFromDate = (date) => (date.getTime() - INITIAL_YEAR_TIMESTAMP) / MILLISECONDS_IN_SECONDS;
17
+ //# sourceMappingURL=time.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"time.js","sourceRoot":"","sources":["../../src/utils/time.ts"],"names":[],"mappings":"AAAA,MAAM,sBAAsB,GAAG,YAAY,CAAC;AAC5C,MAAM,uBAAuB,GAAG,IAAI,CAAC;AAGrC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAE,IAAY,EAAS,EAAE,CAAC,IAAI,IAAI,CAAC,sBAAsB,GAAG,CAAC,IAAI,GAAG,uBAAuB,CAAC,CAAC,CAAC;AAEhI;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAE,IAAU,EAAW,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,sBAAsB,CAAC,GAAG,uBAAuB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,78 @@
1
+ {
2
+ "name": "jooby-codec",
3
+ "version": "1.0.1",
4
+ "description": "Jooby message encoders/decoders",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "exports": {
8
+ ".": "./dist/index.js",
9
+ "./ts": "./src/index.js",
10
+ "./commands": "./dist/commands/index.js",
11
+ "./commands/downlink": "./dist/commands/downlink/index.js",
12
+ "./commands/downlink/*": "./dist/commands/downlink/*.js",
13
+ "./commands/uplink": "./dist/commands/uplink/index.js",
14
+ "./commands/uplink/*": "./dist/commands/uplink/*.js",
15
+ "./utils/*": "./dist/utils/*.js"
16
+ },
17
+ "types": "./dist/index.d.ts",
18
+ "typesVersions": {
19
+ "*": {
20
+ "*": [
21
+ "./dist/index.d.ts",
22
+ "./dist/utils/*.d.ts",
23
+ "./dist/*/index.d.ts"
24
+ ],
25
+ "./utils/*": [
26
+ "./dist/utils/*.d.ts"
27
+ ]
28
+ }
29
+ },
30
+ "files": [
31
+ "/dist"
32
+ ],
33
+ "engines": {
34
+ "npm": ">=9.0.0",
35
+ "node": ">=18.0.0"
36
+ },
37
+ "scripts": {
38
+ "start": "node ./dist/index.js",
39
+ "dev": "nodemon",
40
+ "build:js": "tsc --extendedDiagnostics",
41
+ "build:js:clean": "rm -rf ./dist/ && tsc --incremental false --extendedDiagnostics",
42
+ "build:js:watch": "tsc --watch",
43
+ "build:docs": "typedoc",
44
+ "build:docs:watch": "typedoc --watch --preserveWatchOutput",
45
+ "build": "npm run build:js & npm run build:docs",
46
+ "lint:tsc": "tsc --project ./tsconfig.eslint.json --noEmit",
47
+ "lint:eslint": "eslint ./src ./tests --ext .ts",
48
+ "lint": "npm run lint:tsc && npm run lint:eslint -- --max-warnings=0",
49
+ "lint-cached": "npm run lint:tsc && npm run lint:eslint -- --cache --max-warnings=0",
50
+ "lint:fix": "npm run lint:eslint -- --fix --max-warnings=0",
51
+ "test": "npm run lint && jest",
52
+ "test:watch": "jest --watch",
53
+ "preinstall": "git config core.hooksPath .githooks",
54
+ "publish": "clean-publish"
55
+ },
56
+ "devDependencies": {
57
+ "@types/jest": "^29.5.0",
58
+ "@typescript-eslint/eslint-plugin": "^5.57.0",
59
+ "@typescript-eslint/parser": "^5.57.0",
60
+ "clean-publish": "^4.1.1",
61
+ "eslint": "^8.37.0",
62
+ "eslint-config-airbnb-base": "^15.0.0",
63
+ "eslint-config-airbnb-typescript": "^17.0.0",
64
+ "eslint-import-resolver-typescript": "^3.5.4",
65
+ "eslint-plugin-import": "^2.27.5",
66
+ "eslint-plugin-tsdoc": "^0.2.17",
67
+ "jest": "^29.5.0",
68
+ "nodemon": "^2.0.22",
69
+ "ts-jest": "^29.0.5",
70
+ "ts-node": "^10.9.1",
71
+ "typedoc": "^0.23.28",
72
+ "typedoc-plugin-missing-exports": "^1.0.0",
73
+ "typedoc-theme-hierarchy": "^3.1.0",
74
+ "typedoc-theme-yaf": "^0.0.4",
75
+ "typescript": "^5.0.3"
76
+ },
77
+ "license": "MIT"
78
+ }
package/readme.md ADDED
@@ -0,0 +1,145 @@
1
+ Jooby message encoders/decoders
2
+ ===============================
3
+
4
+ [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/jooby-dev/jooby-codec/test.yml?label=test&style=flat-square)](https://github.com/jooby-dev/jooby-codec/actions)
5
+ [![npm version](https://img.shields.io/npm/v/jooby-codec.svg?style=flat-square)](https://www.npmjs.com/package/jooby-codec)
6
+ [![Docs](https://img.shields.io/badge/docs-orange.svg?style=flat-square)](https://jooby-dev.github.io/jooby-codec)
7
+
8
+ This library contains message encoders and decoders for [Jooby](https://jooby.eu) LoRaWAN devices.
9
+
10
+
11
+ ## Usage
12
+
13
+ Install required dependencies:
14
+
15
+ ```sh
16
+ npm install jooby-codec
17
+ ```
18
+
19
+ Add to the project:
20
+
21
+ ```js
22
+ import {commands, message} from 'jooby-codec';
23
+
24
+ // output all available commands tree
25
+ console.log(commands);
26
+ // all uplink commands
27
+ console.log(commands.uplink);
28
+ // one particular command
29
+ console.log(commands.uplink.getCurrentMul.default);
30
+
31
+ // output main namespace for work with messages
32
+ console.log(message);
33
+ ```
34
+
35
+ But it's better to add only necessary commands to the project:
36
+
37
+ ```js
38
+ // to get only downlink commands
39
+ import {downlink} from 'jooby-codec/commands';
40
+ // or slightly more efficient
41
+ import * as downlink from 'jooby-codec/commands/downlink';
42
+
43
+ // to get one particular command
44
+ import SetTime2000 from 'jooby-codec/commands/downlink/SetTime2000';
45
+ ```
46
+
47
+ The last approach is preferred as it is more efficient and will init only a necessary commands.
48
+
49
+ It's possible to parse messages either from raw [Uint8Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) or HEX string:
50
+
51
+ Parse downlink message:
52
+
53
+ ```js
54
+ // from byte array
55
+ const messageData = message.fromBytes(
56
+ new Uint8Array([
57
+ 0x02, 0x05, 0x4e, 0x00, 0x01, 0xe2, 0x40,
58
+ 0x02, 0x05, 0x4e, 0x00, 0x01, 0xe2, 0x40,
59
+ 0x55
60
+ ]),
61
+ message.TYPE_DOWNLINK
62
+ );
63
+ // or from hex string
64
+ const messageData = message.fromHex(
65
+ '02 05 4e 00 01 e2 40 02 05 4e 00 01 e2 40 55',
66
+ message.TYPE_DOWNLINK
67
+ );
68
+
69
+ // decoded data with commands and checksum
70
+ console.log(messageData);
71
+ /*{
72
+ commands: [
73
+ { data: [Object], command: [SetTime2000] },
74
+ { data: [Object], command: [SetTime2000] }
75
+ ],
76
+ lrc: { expected: 85, actual: 85 },
77
+ isValid: true
78
+ }*/
79
+ ```
80
+
81
+ Parse uplink message:
82
+
83
+ ```js
84
+ const messageData = message.fromHex(
85
+ '02 01 01 18 06 0f 83 01 08 0a 0c 16 08 2f 97 0f 83 01 08 0a 0c ef',
86
+ message.TYPE_UPLINK
87
+ );
88
+ ```
89
+
90
+ It's possible to parse message with autodetect direction:
91
+
92
+ ```js
93
+ const messageData = message.fromHex(
94
+ '02 01 01 18 06 0f 83 01 08 0a 0c 16 08 2f 97 0f 83 01 08 0a 0c ef',
95
+ message.TYPE_AUTO
96
+ );
97
+ // or even shorter as message.TYPE_AUTO is default behavior
98
+ const messageData = message.fromHex(
99
+ '02 01 01 18 06 0f 83 01 08 0a 0c 16 08 2f 97 0f 83 01 08 0a 0c ef'
100
+ );
101
+ ```
102
+ It's best to avoid using message.TYPE_AUTO due to performance penalty.
103
+
104
+ Prepare command and get encoded data:
105
+
106
+ ```js
107
+ import SetTime2000 from 'jooby-codec/commands/downlink/SetTime2000';
108
+
109
+ const command = new SetTime2000({sequenceNumber: 5, time: 9462957});
110
+
111
+ // output command binary in hex representation
112
+ // 02 05 05 00 90 64 ad
113
+ console.log(command.toHex());
114
+ // [2, 5, 5, 0, 144, 100, 173]
115
+ console.log(command.toBytes());
116
+ ```
117
+
118
+ Combine a message from commands:
119
+
120
+ ```js
121
+ const messageBytes = message.toBytes([
122
+ new SetTime2000({sequenceNumber: 78, time: 123456}),
123
+ new GetCurrent()
124
+ ]);
125
+ ```
126
+
127
+ or to get in a hex format:
128
+
129
+ ```js
130
+ const commandInstancesArray = [
131
+ new SetTime2000({status: 1}),
132
+ new DataDayMul({
133
+ channels: [
134
+ {value: 131, index: 0},
135
+ {value: 8, index: 1},
136
+ {value: 10, index: 2},
137
+ {value: 12, index: 3}
138
+ ],
139
+ time: 75660480
140
+ })
141
+ ];
142
+
143
+ const messageBytes = message.toHex(commandInstancesArray, {prefix: '0x'});
144
+ // 0x02 0x05 0x05 0x00 0x90 ...
145
+ ```