From 47add25f6e7edf1b20d2fddb4919c1d97e4da294 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期四, 23 十月 2025 16:57:06 +0800
Subject: [PATCH] 新公司部署相关配置修改

---
 src/api/equipment/monitoring/equipment.js |  203 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 203 insertions(+), 0 deletions(-)

diff --git a/src/api/equipment/monitoring/equipment.js b/src/api/equipment/monitoring/equipment.js
new file mode 100644
index 0000000..4276b98
--- /dev/null
+++ b/src/api/equipment/monitoring/equipment.js
@@ -0,0 +1,203 @@
+// 妯℃嫙宸ヤ笟浠ュお缃�/5G 缃戝叧鏁版嵁鎺ュ叆涓庤繙绋嬫帶鍒讹紙鍓嶇閫犳暟锛�
+// 璁惧鍥寸粫鐓ょ偔鍔犲伐鍦烘櫙锛氬甫寮忚緭閫佹満銆佺牬纰庢満銆佺毊甯︾Г銆侀櫎灏橀鏈恒�佺粰鐓ゆ満绛�
+
+const DEFAULT_THRESHOLDS = {
+  temperatureC: 85, // 鈩�
+  pressureBar: 12, // bar
+  currentA: 180, // A
+  voltageV: 420, // V锛堜笁鐩哥嚎鐢靛帇锛�
+  powerFactor: 0.85 // cos蠁
+}
+
+const STORAGE_KEYS = {
+  thresholds: 'monitor_equipment_thresholds',
+  channels: 'monitor_equipment_alarm_channels'
+}
+
+const DEFAULT_CHANNELS = {
+  platform: true,
+  sms: false,
+  voice: false
+}
+
+const BASE_EQUIPMENTS = [
+  { id: 'conv-01', name: '涓荤叅娴佸甫寮忚緭閫佹満#1', location: '绛涘垎杞﹂棿涓�绾�', type: 'conveyor' },
+  { id: 'crusher-01', name: '榻胯緤鐮寸鏈�#1', location: '鐮寸宸ユ', type: 'crusher' },
+  { id: 'feeder-01', name: '鐢垫満鎸姩缁欑叅鏈�#1', location: '鍘熺叅浠撲笅鍙�', type: 'feeder' },
+  { id: 'blower-01', name: '闄ゅ皹绂诲績椋庢満#1', location: '瑁呰溅闄ゅ皹鐐�', type: 'blower' },
+  { id: 'scale-01', name: '鐨甫绉�#1', location: '璁¢噺娈�', type: 'beltScale' }
+]
+
+function getRandomAround(base, fluct = 0.05) {
+  const delta = base * fluct
+  return +(base + (Math.random() * 2 - 1) * delta).toFixed(2)
+}
+
+function seededInitMetrics(type) {
+  switch (type) {
+    case 'conveyor':
+      return { temperatureC: 55, pressureBar: 6.5, currentA: 95, voltageV: 400, powerFactor: 0.92 }
+    case 'crusher':
+      return { temperatureC: 65, pressureBar: 10.5, currentA: 140, voltageV: 405, powerFactor: 0.9 }
+    case 'feeder':
+      return { temperatureC: 50, pressureBar: 5.5, currentA: 60, voltageV: 398, powerFactor: 0.93 }
+    case 'blower':
+      return { temperatureC: 70, pressureBar: 8.2, currentA: 120, voltageV: 402, powerFactor: 0.88 }
+    case 'beltScale':
+      return { temperatureC: 48, pressureBar: 0.0, currentA: 35, voltageV: 401, powerFactor: 0.95 }
+    default:
+      return { temperatureC: 55, pressureBar: 6, currentA: 90, voltageV: 400, powerFactor: 0.9 }
+  }
+}
+
+function nextMetrics(current, type) {
+  const drift = {
+    temperatureC: getRandomAround(current.temperatureC, 0.03),
+    pressureBar: getRandomAround(current.pressureBar, 0.06),
+    currentA: getRandomAround(current.currentA, 0.08),
+    voltageV: getRandomAround(current.voltageV, 0.01),
+    powerFactor: Math.max(0.6, Math.min(0.99, getRandomAround(current.powerFactor, 0.02)))
+  }
+  if (type === 'crusher') drift.currentA += Math.random() * 4 - 2
+  if (type === 'blower') drift.powerFactor -= Math.random() * 0.01
+  return {
+    temperatureC: +drift.temperatureC.toFixed(2),
+    pressureBar: +drift.pressureBar.toFixed(2),
+    currentA: +drift.currentA.toFixed(2),
+    voltageV: +drift.voltageV.toFixed(2),
+    powerFactor: +drift.powerFactor.toFixed(2)
+  }
+}
+
+export function getThresholds() {
+  try {
+    const raw = localStorage.getItem(STORAGE_KEYS.thresholds)
+    if (!raw) return { ...DEFAULT_THRESHOLDS }
+    const obj = JSON.parse(raw)
+    return { ...DEFAULT_THRESHOLDS, ...obj }
+  } catch (e) {
+    return { ...DEFAULT_THRESHOLDS }
+  }
+}
+
+export function saveThresholds(thresholds) {
+  const merged = { ...DEFAULT_THRESHOLDS, ...thresholds }
+  localStorage.setItem(STORAGE_KEYS.thresholds, JSON.stringify(merged))
+  return merged
+}
+
+export function getAlarmChannels() {
+  try {
+    const raw = localStorage.getItem(STORAGE_KEYS.channels)
+    if (!raw) return { ...DEFAULT_CHANNELS }
+    const obj = JSON.parse(raw)
+    return { ...DEFAULT_CHANNELS, ...obj }
+  } catch (e) {
+    return { ...DEFAULT_CHANNELS }
+  }
+}
+
+export function saveAlarmChannels(channels) {
+  const merged = { ...DEFAULT_CHANNELS, ...channels }
+  localStorage.setItem(STORAGE_KEYS.channels, JSON.stringify(merged))
+  return merged
+}
+
+// 璁㈤槄瀹炴椂鏁版嵁锛堟ā鎷熶綆鏃跺欢銆侀珮鍙潬閾捐矾锛�
+export function subscribeEquipmentData(callback, options = {}) {
+  const { intervalMs = 1000, streaming = true } = options
+  let isStopped = false
+
+  const equipmentStates = BASE_EQUIPMENTS.map(e => ({
+    ...e,
+    status: 'RUNNING',
+    metrics: seededInitMetrics(e.type)
+  }))
+
+  // 闈炴祦妯″紡锛氫粎鎺ㄩ�佷竴娆″揩鐓�
+  if (!streaming) {
+    const now = Date.now()
+    equipmentStates.forEach(es => {
+      callback({
+        ts: now,
+        equipmentId: es.id,
+        name: es.name,
+        location: es.location,
+        status: es.status,
+        metrics: { ...es.metrics }
+      })
+    })
+    return () => {}
+  }
+
+  function tick() {
+    if (isStopped) return
+    const now = Date.now()
+    equipmentStates.forEach(es => {
+      if (Math.random() < 0.01) {
+        es.status = es.status === 'RUNNING' ? 'STOPPED' : 'RUNNING'
+      }
+      if (es.status === 'RUNNING') {
+        es.metrics = nextMetrics(es.metrics, es.type)
+      } else {
+        es.metrics = {
+          ...es.metrics,
+          currentA: +(es.metrics.currentA * 0.1).toFixed(2),
+          powerFactor: Math.max(0.5, +(es.metrics.powerFactor * 0.8).toFixed(2))
+        }
+      }
+      callback({
+        ts: now,
+        equipmentId: es.id,
+        name: es.name,
+        location: es.location,
+        status: es.status,
+        metrics: { ...es.metrics }
+      })
+    })
+    timer = setTimeout(tick, intervalMs)
+  }
+
+  let timer = setTimeout(tick, intervalMs)
+  return () => {
+    isStopped = true
+    if (timer) clearTimeout(timer)
+  }
+}
+
+export function sendControlCommand(equipmentId, action) {
+  return new Promise(resolve => {
+    const delay = 50 + Math.round(Math.random() * 70)
+    setTimeout(() => {
+      resolve({ code: 200, msg: 'OK', data: { equipmentId, action, acceptedAt: Date.now() } })
+      /* eslint-disable no-console */
+      console.log(`[CONTROL] equipment=${equipmentId} action=${action}`)
+    }, delay)
+  })
+}
+
+export function detectAlarms(metrics, thresholds) {
+  const over = []
+  if (metrics.temperatureC > thresholds.temperatureC) over.push({ field: 'temperatureC', value: metrics.temperatureC, threshold: thresholds.temperatureC })
+  if (metrics.pressureBar > thresholds.pressureBar) over.push({ field: 'pressureBar', value: metrics.pressureBar, threshold: thresholds.pressureBar })
+  if (metrics.currentA > thresholds.currentA) over.push({ field: 'currentA', value: metrics.currentA, threshold: thresholds.currentA })
+  if (metrics.voltageV > thresholds.voltageV) over.push({ field: 'voltageV', value: metrics.voltageV, threshold: thresholds.voltageV })
+  if (metrics.powerFactor < thresholds.powerFactor) over.push({ field: 'powerFactor', value: metrics.powerFactor, threshold: thresholds.powerFactor })
+  return over
+}
+
+export function listEquipments() {
+  return BASE_EQUIPMENTS.map(e => ({ id: e.id, name: e.name, location: e.location, type: e.type }))
+}
+
+export default {
+  subscribeEquipmentData,
+  sendControlCommand,
+  detectAlarms,
+  getThresholds,
+  saveThresholds,
+  getAlarmChannels,
+  saveAlarmChannels,
+  listEquipments
+}
+

--
Gitblit v1.9.3