poe-svelte-ui-lib 1.65.0 → 1.66.0
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.
- package/README.md +1 -1
- package/dist/protocols/can.d.ts +1 -0
- package/dist/protocols/can.js +3 -0
- package/dist/protocols/dictionary.d.ts +4 -0
- package/dist/protocols/dictionary.js +68 -0
- package/dist/protocols/index.d.ts +3 -2
- package/dist/protocols/index.js +4 -2
- package/dist/protocols/poeSerial.d.ts +1 -0
- package/dist/protocols/poeSerial.js +18 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -59,7 +59,7 @@ npm install poe-svelte-ui-lib
|
|
|
59
59
|
|
|
60
60
|
**Названия смарт-виджетов** — в словаре библиотеки на всех языках (WiFi, «Об устройстве», «Файловая система», «Стек и задачи», «RGB лента», «Пилотажный дисплей», «Карта»); пустой `label.name` показывает название на языке пользователя, `widgetTitle(type)` отдаёт его сразу на всех языках `{ ru, en, zh }` — так конструктор заполняет заголовок нового виджета.
|
|
61
61
|
|
|
62
|
-
**Ядро протоколов** — `poe-svelte-ui-lib/protocols` (без Svelte, работает и под Node без Vite): общий для DevCloud, WebApp и SYP-DevTerminal CBOR-кодек (RFC 8949) — `encodeCbor`/`decodeCbor`, `CborEncoder`/`CborDecoder`; `valueToCbor`/`cborToValue` — обычные значения, двоичные данные как `Uint8Array` (WebSocket, хранилище, телеметрия); `jsonToCbor`/`cborToJson` — JSON-совместимые значения, двоичные данные в base64, строки под ключами с `BIN` — байты (поля ввода терминала и отладки). Пакет `poe_cbor_pkt` `{ TrgBusID : [RetBusID, HA_Code, Payload, CRC16] }` (CAN, RS485): `encodePacket`/`decodePacket` (разбор с начала буфера — `complete` с длиной, `incomplete` для потока или `garbage`; объекты с одинаковым `TrgBusID` не склеиваются, неверный CRC — флаг `crcOk`), `objectsFor` (свой адрес и broadcast `0xFFFF`), `makeHaCode`/`splitHaCode`, `packetObjectCrc`; контрольные суммы `crc16Kermit` и `crc8Rohc`. Байты совпадают с `poe_cbor_pkt.c` прошивки — проверка `npm run TestProtocols` (`tests/protocols.test.mjs`, эталонные пакеты собраны прошивочным кодом). Рамка POESerial (UART-консоль `system_console`, `[SOH] HDR [US] ARG [STX] VAL [ETX] CRC8 [US] FHS [EOT]`): `encodePoeSerialFrame` — команда устройству, `createPoeSerialParser().push(байты)` — потоковый разбор кадров, строк Teleplot (`plot`) и прочего текста (`raw`), с проверкой CRC `crc8RohcUtf8` по правилу прошивки (`crc8_rohc` в `common.c`). CAN/CAN FD через slcan-адаптер (`can_service` прошивки): `canFragments`/`encodeCanPacket` — нарезка пакета на кадры как `CAN_Send` (бит 10 ID — «последний», биты 0..9 — `packetId`, по 8 / 64 байта), `encodeSlcanFrame`, `createCanParser().push(байты)` — разбор кадров slcan со сборкой фрагментов и обрезкой паддинга CAN FD. RS485 — сырой поток пакетов: `createPacketStreamParser().push(байты)` (пауза обрывает недособранное, мусор пропускается по байту). Своих копий протоколов в приложениях не держим: терминал
|
|
62
|
+
**Ядро протоколов** — `poe-svelte-ui-lib/protocols` (без Svelte, работает и под Node без Vite): общий для DevCloud, WebApp и SYP-DevTerminal CBOR-кодек (RFC 8949) — `encodeCbor`/`decodeCbor`, `CborEncoder`/`CborDecoder`; `valueToCbor`/`cborToValue` — обычные значения, двоичные данные как `Uint8Array` (WebSocket, хранилище, телеметрия); `jsonToCbor`/`cborToJson` — JSON-совместимые значения, двоичные данные в base64, строки под ключами с `BIN` — байты (поля ввода терминала и отладки). Пакет `poe_cbor_pkt` `{ TrgBusID : [RetBusID, HA_Code, Payload, CRC16] }` (CAN, RS485): `encodePacket`/`decodePacket` (разбор с начала буфера — `complete` с длиной, `incomplete` для потока или `garbage`; объекты с одинаковым `TrgBusID` не склеиваются, неверный CRC — флаг `crcOk`), `objectsFor` (свой адрес и broadcast `0xFFFF`), `makeHaCode`/`splitHaCode`, `packetObjectCrc`; контрольные суммы `crc16Kermit` и `crc8Rohc`. Байты совпадают с `poe_cbor_pkt.c` прошивки — проверка `npm run TestProtocols` (`tests/protocols.test.mjs`, эталонные пакеты собраны прошивочным кодом). Рамка POESerial (UART-консоль `system_console`, `[SOH] HDR [US] ARG [STX] VAL [ETX] CRC8 [US] FHS [EOT]`): `encodePoeSerialFrame` — команда устройству, `createPoeSerialParser().push(байты)` — потоковый разбор кадров, строк Teleplot (`plot`) и прочего текста (`raw`), с проверкой CRC `crc8RohcUtf8` по правилу прошивки (`crc8_rohc` в `common.c`). CAN/CAN FD через slcan-адаптер (`can_service` прошивки): `canFragments`/`encodeCanPacket` — нарезка пакета на кадры как `CAN_Send` (бит 10 ID — «последний», биты 0..9 — `packetId`, по 8 / 64 байта), `encodeSlcanFrame`, `createCanParser().push(байты)` — разбор кадров slcan со сборкой фрагментов и обрезкой паддинга CAN FD. RS485 — сырой поток пакетов: `createPacketStreamParser().push(байты)` (пауза обрывает недособранное, мусор пропускается по байту). Открытие slcan-адаптера — `slcanOpenCommands(скорость, скоростьДанных?)`. Поле Value команды POESerial из ввода — `poeSerialValueFromText` (hex как есть, JSON → CBOR). Словарь протокола — `HEADER_CODES`, `DEFAULT_ARGUMENT_CODES` (из `.framework/Dictionary.yaml` прошивок), `parseArgumentDictionary` (строки `- [Строка, Enum, Число]`), `nameByCode`. Своих копий протоколов и словаря в приложениях не держим: терминал и отладка облака читают и пишут порт сырыми байтами, разбор и сборка — здесь.
|
|
63
63
|
|
|
64
64
|
**Шапка смарт-виджета** (`WidgetHeader`): значок, заголовок и сворачивание слева, «?» в правом краю; правая часть (режимы, «Обновить» и т. п.) стоит в той же строке, а если не помещается — уходит второй строкой под заголовок и там переносится.
|
|
65
65
|
|
package/dist/protocols/can.d.ts
CHANGED
package/dist/protocols/can.js
CHANGED
|
@@ -102,3 +102,6 @@ export const createCanParser = ({ sessionTimeoutMs = 2000, maxPacketBytes = 8192
|
|
|
102
102
|
},
|
|
103
103
|
};
|
|
104
104
|
};
|
|
105
|
+
/* Команды открытия slcan-адаптера (CANable и совместимые): закрыть канал, скорость арбитража (S0..S8, SA..SD), для CAN FD — скорость данных
|
|
106
|
+
(Y1..Y5), нормальный режим, без автоповтора, открыть канал — каждая строка заканчивается \r */
|
|
107
|
+
export const slcanOpenCommands = (bitrate, dataBitrate) => ["C", bitrate, ...(dataBitrate ? [dataBitrate] : []), "M0", "A0", "O"].map((command) => `${command}\r`);
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare const HEADER_CODES: Record<string, number>;
|
|
2
|
+
export declare const DEFAULT_ARGUMENT_CODES: Record<string, number>;
|
|
3
|
+
export declare const parseArgumentDictionary: (text: string) => Record<string, number>;
|
|
4
|
+
export declare const nameByCode: (codes: Record<string, number>, code: number) => string;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/* $lib/protocols/dictionary.ts */
|
|
2
|
+
/* Словарь заголовков и аргументов протокола HA_Code — заголовок в 2 старших битах, аргумент в 14 младших (makeHaCode). Аргументы по умолчанию —
|
|
3
|
+
из .framework/Dictionary.yaml прошивок (ProdFactory-ESP и ProdFactory-STM, одинаковые); у устройства словарь может быть свой — его загружают
|
|
4
|
+
из файла (parseArgumentDictionary), своих копий словаря в приложениях не держим */
|
|
5
|
+
export const HEADER_CODES = {
|
|
6
|
+
GET: 0,
|
|
7
|
+
SET: 1,
|
|
8
|
+
"OK!": 2,
|
|
9
|
+
"ER!": 3,
|
|
10
|
+
};
|
|
11
|
+
export const DEFAULT_ARGUMENT_CODES = {
|
|
12
|
+
Unknown: 0,
|
|
13
|
+
Restart: 1,
|
|
14
|
+
DefCfg: 2,
|
|
15
|
+
DlFW: 3,
|
|
16
|
+
RstNVS: 5,
|
|
17
|
+
LocTime: 6,
|
|
18
|
+
Update: 7,
|
|
19
|
+
StackInfo: 8,
|
|
20
|
+
BackUp: 9,
|
|
21
|
+
BindMKey: 10,
|
|
22
|
+
DataStream: 15,
|
|
23
|
+
APsList: 21,
|
|
24
|
+
FS: 22,
|
|
25
|
+
JoinDev: 23,
|
|
26
|
+
JoinUser: 24,
|
|
27
|
+
LeaveUser: 25,
|
|
28
|
+
ModFind: 31,
|
|
29
|
+
ModList: 32,
|
|
30
|
+
ModCap: 33,
|
|
31
|
+
ModInfo: 34,
|
|
32
|
+
ModMode: 35,
|
|
33
|
+
ModCfg: 36,
|
|
34
|
+
ModT1: 37,
|
|
35
|
+
ModT2: 38,
|
|
36
|
+
ModT3: 39,
|
|
37
|
+
ModT4: 40,
|
|
38
|
+
ModT5: 41,
|
|
39
|
+
ModS1: 42,
|
|
40
|
+
ModS2: 43,
|
|
41
|
+
ModS3: 44,
|
|
42
|
+
ModS4: 45,
|
|
43
|
+
ModS5: 46,
|
|
44
|
+
FwUpgS: 51,
|
|
45
|
+
FwUpgP: 52,
|
|
46
|
+
FwUpgD: 53,
|
|
47
|
+
FwUpgE: 54,
|
|
48
|
+
FDwS: 65,
|
|
49
|
+
FDwP: 66,
|
|
50
|
+
FDwD: 67,
|
|
51
|
+
FDwE: 68,
|
|
52
|
+
TestReq: 91,
|
|
53
|
+
MotInit: 111,
|
|
54
|
+
MotMode: 112,
|
|
55
|
+
MotPos: 113,
|
|
56
|
+
MotPID: 114,
|
|
57
|
+
MotInfo: 115,
|
|
58
|
+
MotCfg: 116,
|
|
59
|
+
MotCal: 117,
|
|
60
|
+
OrData: 141,
|
|
61
|
+
OrOfs: 142,
|
|
62
|
+
OrAccCal: 143,
|
|
63
|
+
OrMagCal: 144,
|
|
64
|
+
};
|
|
65
|
+
/* Аргументы из текста Dictionary.yaml (или его фрагмента): строки «- [Строка, Enum, Число]», комментарии и прочее пропускаются */
|
|
66
|
+
export const parseArgumentDictionary = (text) => Object.fromEntries([...text.matchAll(/^\s*-\s*\[\s*([^,\]]+?)\s*,\s*[^,\]]+?\s*,\s*(\d+)\s*\]/gm)].map(([, name, code]) => [name, Number(code)]));
|
|
67
|
+
/* Имя по коду (обратный поиск) — для показа принятых пакетов; неизвестный код — числом */
|
|
68
|
+
export const nameByCode = (codes, code) => Object.entries(codes).find(([, value]) => value === code)?.[0] ?? String(code);
|
|
@@ -6,5 +6,6 @@ export { CborToValue, ValueToCbor, cborToValue, valueToCbor } from "./cbor/value
|
|
|
6
6
|
export { CborToJson, JsonToCbor, cborToJson, jsonToCbor } from "./cbor/json.js";
|
|
7
7
|
export { crc16Kermit, crc8Rohc, crc8RohcUtf8 } from "./crc.js";
|
|
8
8
|
export { BROADCAST_BUS_ID, makeHaCode, splitHaCode, packetObjectCrc, encodePacket, decodePacket, objectsFor, createPacketStreamParser, type PacketObject, type DecodedPacketObject, type PacketParse, } from "./packet.js";
|
|
9
|
-
export { encodePoeSerialFrame, createPoeSerialParser, type PoeSerialItem } from "./poeSerial.js";
|
|
10
|
-
export { CAN_FINAL_BIT, CAN_PACKET_ID_MASK, canFragments, encodeSlcanFrame, encodeCanPacket, createCanParser, type CanFrame, type CanMessage } from "./can.js";
|
|
9
|
+
export { encodePoeSerialFrame, createPoeSerialParser, poeSerialValueFromText, type PoeSerialItem } from "./poeSerial.js";
|
|
10
|
+
export { CAN_FINAL_BIT, CAN_PACKET_ID_MASK, canFragments, encodeSlcanFrame, encodeCanPacket, createCanParser, slcanOpenCommands, type CanFrame, type CanMessage, } from "./can.js";
|
|
11
|
+
export { HEADER_CODES, DEFAULT_ARGUMENT_CODES, parseArgumentDictionary, nameByCode } from "./dictionary.js";
|
package/dist/protocols/index.js
CHANGED
|
@@ -13,6 +13,8 @@ export { CborToJson, JsonToCbor, cborToJson, jsonToCbor } from "./cbor/json.js";
|
|
|
13
13
|
export { crc16Kermit, crc8Rohc, crc8RohcUtf8 } from "./crc.js";
|
|
14
14
|
export { BROADCAST_BUS_ID, makeHaCode, splitHaCode, packetObjectCrc, encodePacket, decodePacket, objectsFor, createPacketStreamParser, } from "./packet.js";
|
|
15
15
|
/* Рамка POESerial (UART-консоль system_console): сборка команды и потоковый разбор кадров, строк Teleplot и текста */
|
|
16
|
-
export { encodePoeSerialFrame, createPoeSerialParser } from "./poeSerial.js";
|
|
16
|
+
export { encodePoeSerialFrame, createPoeSerialParser, poeSerialValueFromText } from "./poeSerial.js";
|
|
17
17
|
/* CAN/CAN FD через slcan-адаптер: нарезка пакета на кадры как в can_service прошивки, кадры slcan, потоковый разбор со сборкой фрагментов */
|
|
18
|
-
export { CAN_FINAL_BIT, CAN_PACKET_ID_MASK, canFragments, encodeSlcanFrame, encodeCanPacket, createCanParser } from "./can.js";
|
|
18
|
+
export { CAN_FINAL_BIT, CAN_PACKET_ID_MASK, canFragments, encodeSlcanFrame, encodeCanPacket, createCanParser, slcanOpenCommands, } from "./can.js";
|
|
19
|
+
/* Словарь заголовков и аргументов HA_Code — по умолчанию из Dictionary.yaml прошивок, разбор файла словаря */
|
|
20
|
+
export { HEADER_CODES, DEFAULT_ARGUMENT_CODES, parseArgumentDictionary, nameByCode } from "./dictionary.js";
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
по HEADER+ARGUMENT+VALUE (crc8RohcUtf8), FHS (свободная куча) только у кадров устройства. Устройство шлёт VALUE текстом (лог или hex-дамп CBOR),
|
|
4
4
|
устройству VALUE уходит сырыми байтами CBOR. Между кадрами — текст: строки Teleplot «>Имя:Значение» (PLOT) и прочий вывод (RAW) */
|
|
5
5
|
import { crc8RohcUtf8 } from "./crc.js";
|
|
6
|
+
import { jsonToCbor } from "./cbor/json.js";
|
|
6
7
|
export const SOH = 0x01;
|
|
7
8
|
export const STX = 0x02;
|
|
8
9
|
export const ETX = 0x03;
|
|
@@ -110,3 +111,20 @@ export const createPoeSerialParser = () => {
|
|
|
110
111
|
},
|
|
111
112
|
};
|
|
112
113
|
};
|
|
114
|
+
/* Поле Value команды из ввода пользователя: пусто — без тела, hex-строка (с пробелами или без) — готовые байты как есть, иначе JSON → CBOR
|
|
115
|
+
(двоичные данные — base64, ключи с BIN — байты, см. jsonToCbor); не hex и не JSON — ошибка */
|
|
116
|
+
export const poeSerialValueFromText = (text) => {
|
|
117
|
+
const trimmed = (text ?? "").trim();
|
|
118
|
+
if (!trimmed)
|
|
119
|
+
return new Uint8Array();
|
|
120
|
+
if (/^([0-9A-Fa-f]{2}\s?)+$/.test(trimmed))
|
|
121
|
+
return Uint8Array.from(trimmed.replace(/\s/g, "").match(/../g) ?? [], (pair) => parseInt(pair, 16));
|
|
122
|
+
let parsed;
|
|
123
|
+
try {
|
|
124
|
+
parsed = JSON.parse(trimmed);
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
throw new Error(`Value не является ни hex, ни JSON: ${trimmed}`);
|
|
128
|
+
}
|
|
129
|
+
return jsonToCbor(parsed);
|
|
130
|
+
};
|