From 644c7a8a78a1e6593883d236eb60f0ee74424faa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B2=D0=BE=D0=B2=20=D0=90=D1=80=D1=82?= =?UTF-8?q?=D0=B5=D0=BC?= Date: Thu, 2 Jul 2026 22:27:06 +0300 Subject: [PATCH] =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=BF=D0=BE=D0=B4=D0=B4=D0=B5=D1=80=D0=B6=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=B4=D0=B5=D0=B2=20=D0=BE=D0=BA=D1=80=D1=83=D0=B6?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/handlers/demo-modbus.ts | 63 +++++++++++++++++++++++++++++++++ app/src/handlers/demo-plc.ts | 11 ++++-- app/src/handlers/index.ts | 2 ++ docker-compose.yml | 1 + 4 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 app/src/handlers/demo-modbus.ts diff --git a/app/src/handlers/demo-modbus.ts b/app/src/handlers/demo-modbus.ts new file mode 100644 index 0000000..a03aec9 --- /dev/null +++ b/app/src/handlers/demo-modbus.ts @@ -0,0 +1,63 @@ +import type { TopicHandler } from '../types.js' + +export const TOPIC = 'data/demo/modbus/v1' + +const EDGE = 'demo' +const REGISTER_COUNT = 125 +const DEMO_CLOUD_INGEST_URL = process.env.DEMO_CLOUD_INGEST_URL + +type DemoModbusMetric = { + edge: string + timestamp: string + tag: string + value: number +} + +function parseValues(payload: Buffer): number[] { + const values = JSON.parse(payload.toString('utf8')) as number[] + assertRegisterCount(values) + return values +} + +function assertRegisterCount(values: number[]): void { + if (values.length !== REGISTER_COUNT) { + throw new Error(`Expected ${REGISTER_COUNT} modbus values, got ${values.length}`) + } +} + +function toMetrics(values: number[], timestamp: string): DemoModbusMetric[] { + return values.map((value, index) => ({ + edge: EDGE, + timestamp, + tag: `${EDGE}.modbus.${index + 1}`, + value, + })) +} + +async function postMetrics(metrics: DemoModbusMetric[]): Promise { + for (const metric of metrics) { + const response = await fetch(DEMO_CLOUD_INGEST_URL as string, { + method: 'POST', + headers: { + 'content-type': 'application/json', + 'x-api-key': process.env.CLOUD_INGEST_API_KEY as string, + }, + body: JSON.stringify(metric), + }) + + if (!response.ok) { + const text = await response.text() + throw new Error(text) + } + } + + console.log('demo.modbus.posted', { count: metrics.length }) +} + +export const handleDemoModbus: TopicHandler = async (topic, payload) => { + console.log('demo.modbus.received', { topic, bytes: payload.length }) + + const values = parseValues(payload) + const metrics = toMetrics(values, new Date().toISOString()) + await postMetrics(metrics) +} diff --git a/app/src/handlers/demo-plc.ts b/app/src/handlers/demo-plc.ts index 24bafff..12ec73c 100644 --- a/app/src/handlers/demo-plc.ts +++ b/app/src/handlers/demo-plc.ts @@ -1,10 +1,10 @@ -import { postCloudIngest } from '../cloud-ingest.js' import { parseJson } from '../helpers/parse.js' import type { TopicHandler } from '../types.js' export const TOPIC = 'data/demo/plc/v1' const EDGE = 'demo' +const DEMO_CLOUD_INGEST_URL = process.env.DEMO_CLOUD_INGEST_URL type DemoPlcPayload = { tag: string @@ -28,7 +28,14 @@ function toMetric(payload: DemoPlcPayload, timestamp: string): DemoPlcMetric { } async function postMetric(metric: DemoPlcMetric): Promise { - const response = await postCloudIngest(metric) + const response = await fetch(DEMO_CLOUD_INGEST_URL as string, { + method: 'POST', + headers: { + 'content-type': 'application/json', + 'x-api-key': process.env.CLOUD_INGEST_API_KEY as string, + }, + body: JSON.stringify(metric), + }) if (!response.ok) { const text = await response.text() diff --git a/app/src/handlers/index.ts b/app/src/handlers/index.ts index c5f58c9..0f84d36 100644 --- a/app/src/handlers/index.ts +++ b/app/src/handlers/index.ts @@ -1,4 +1,5 @@ import { register } from '../registry.js' +import { handleDemoModbus, TOPIC as demoModbus } from './demo-modbus.js' import { handleDemoPlc, TOPIC as demoPlc } from './demo-plc.js' import { handleEdge5Modbus, TOPIC as edge5Modbus } from './edge5-modbus.js' import { @@ -7,6 +8,7 @@ import { } from './edge5-modbus-v2.js' import { handleEdge5Video, TOPIC as edge5Video } from './edge5-video.js' +register(demoModbus, handleDemoModbus) register(demoPlc, handleDemoPlc) register(edge5Modbus, handleEdge5Modbus) register(edge5ModbusV2, handleEdge5ModbusV2) diff --git a/docker-compose.yml b/docker-compose.yml index 5c503f8..87f03d7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -21,6 +21,7 @@ services: WS_PORT: "9090" CLOUD_INGEST_URL: ${CLOUD_INGEST_URL:-https://demo.backend.drill.greact.ru/ingest} CLOUD_INGEST_API_KEY: ${CLOUD_INGEST_API_KEY:-} + DEMO_CLOUD_INGEST_URL: ${DEMO_CLOUD_INGEST_URL:-} EDGE5_MODBUS_V2_MAPPING_FILE: ${EDGE5_MODBUS_V2_MAPPING_FILE:-/app/src/mappings/edge5-modbus.json} volumes: -- 2.49.1