From 638eaea5faa66b46ebb420b152507c1cd91f51f9 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: Sun, 21 Jun 2026 03:40:33 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A1=D0=BA=D0=BE=D1=80=D1=80=D0=B5=D0=BA?= =?UTF-8?q?=D1=82=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BB=20getMetricStatus=20?= =?UTF-8?q?-=20=D0=BC=D0=B5=D1=82=D0=BE=D0=B4,=20=D0=BA=D0=BE=D1=82=D0=BE?= =?UTF-8?q?=D1=80=D1=8B=D0=B9=20=D0=B2=D0=BB=D0=B8=D1=8F=D0=BB=20=D0=BD?= =?UTF-8?q?=D0=B0=20=D0=BE=D1=82=D0=BE=D0=B1=D1=80=D0=B0=D0=B6=D0=B0=D0=B5?= =?UTF-8?q?=D0=BC=D1=8B=D0=B9=20=D1=81=D1=82=D0=B0=D1=82=D1=83=D1=81=20?= =?UTF-8?q?=D0=BF=D0=BE=D0=BA=D0=B0=D0=B7=D0=B0=D1=82=D0=B5=D0=BB=D1=8F.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/entities/tag/types.ts | 4 ++-- src/utils/metricStatus.ts | 16 +++++++++------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/entities/tag/types.ts b/src/entities/tag/types.ts index 0a750c7..b65c656 100644 --- a/src/entities/tag/types.ts +++ b/src/entities/tag/types.ts @@ -2,8 +2,8 @@ export type TagItem = { id: string; name: string; tagGroup: string | null; - min: number; - max: number; + min: number | null; + max: number | null; comment: string; unitOfMeasurement: string; edgeIds: string[]; diff --git a/src/utils/metricStatus.ts b/src/utils/metricStatus.ts index dd50510..10be0bd 100644 --- a/src/utils/metricStatus.ts +++ b/src/utils/metricStatus.ts @@ -8,17 +8,19 @@ export type MetricStatusInfo = { ageSeconds: number; }; -/** Классифицирует показатель по свежести данных до подключения реальных аварийных правил. */ +function isConfiguredLimit(value: number | null): value is number { + return typeof value === 'number' && Number.isFinite(value); +} + +/** Классифицирует показатель по уставкам min/max из справочника tag. */ export function getMetricStatus(item: CurrentItem, now = Date.now()): MetricStatusInfo { const measuredAt = new Date(item.time).getTime(); const ageSeconds = Number.isFinite(measuredAt) ? Math.max(0, Math.round((now - measuredAt) / 1000)) : Number.POSITIVE_INFINITY; + const belowMin = isConfiguredLimit(item.min) && item.value < item.min; + const aboveMax = isConfiguredLimit(item.max) && item.value > item.max; - if (ageSeconds > 300) { - return { status: 'critical', label: 'нет связи', ageSeconds }; - } - - if (ageSeconds > 30) { - return { status: 'warning', label: 'устарело', ageSeconds }; + if (belowMin || aboveMax) { + return { status: 'critical', label: 'за пределами уставки', ageSeconds }; } return { status: 'normal', label: 'норма', ageSeconds };