فهرست منبع

feat(views): 优化“实时监测”页面的设备配置对话框

1. 支持阀门弹窗
2. 动态获取并展示参数
3. 按指定顺序排序参数
4. 优化参数名称的显示
wangcong 1 روز پیش
والد
کامیت
b848fad8f6

+ 2 - 2
src/components/visual-2d/Visual2DPreview.vue

@@ -15,7 +15,7 @@ const props = defineProps<Props>();
 
 const emit = defineEmits<{
   click: [];
-  openDevCtrlModal: [id: number];
+  openDevCtrlModal: [id: number, valveType: number];
 }>();
 
 const iframeRef = useTemplateRef('previewIframe');
@@ -57,7 +57,7 @@ const handleIframeMsg = (e: MessageEvent<IframeMsg>) => {
   } else if (msgType === getVisual2DMsgType(Visual2DMsgType.PreviewClicked)) {
     emit('click');
   } else if (msgType === getVisual2DMsgType(Visual2DMsgType.OpenDevCtrlModal)) {
-    emit('openDevCtrlModal', e.data.hvacDeviceId);
+    emit('openDevCtrlModal', e.data.hvacDeviceId, e.data.hvacValveType);
   }
 };
 

+ 2 - 1
src/constants/device-params.ts

@@ -5,6 +5,7 @@ export const enum DevParamCommon {
   禁启用状态 = 'disableEnableStatus',
   手自动状态 = 'manualAutoStatus',
   手动启停 = 'startStopOrder',
+  频率控制模式 = 'frequControlMode',
 }
 
 /**
@@ -65,7 +66,7 @@ export const enum DevParamChillerUnit {
   负载率 = 'loadRatio',
   负载率限制设定值 = 'loadRatioLimitSet',
   本地远程状态 = 'localRemoteStatus',
-  运行时间 = 'runHours',
+  运行时间 = 'unitRunHours',
   自动启停指令 = 'semiAutoStartStopOrder',
   冷冻水出水温度设定值 = 'evapWaterTempOutSet',
   冷冻水出水温度设定值反馈 = 'evapWaterTempOutSetFb',

+ 8 - 0
src/views/device-work-status/device-card/index.ts

@@ -43,6 +43,14 @@ export const enum DeviceType {
   其他设备 = 17,
 }
 
+export const enum ValveType {
+  冷冻侧阀 = 101,
+  冷却侧阀 = 102,
+  进口阀 = 103,
+  出口阀 = 104,
+  旁通阀 = 105,
+}
+
 /**
  * 设备卡片数据对象
  * - 以设备类型的中文名称作为 key

+ 235 - 206
src/views/real-time-monitor/DeviceCtrlModal.vue

@@ -2,22 +2,32 @@
 import { computed, onUnmounted, ref, watch } from 'vue';
 import { useRouter } from 'vue-router';
 import { useFullscreen } from '@vueuse/core';
-import { Modal } from 'ant-design-vue';
 
+import BitSwitchConfirm from '@/components/BitSwitchConfirm.vue';
+import InputSave from '@/components/InputSave.vue';
 import SvgIcon from '@/components/SvgIcon.vue';
 import { useRequest } from '@/hooks/request';
 import { useViewVisible } from '@/hooks/view-visible';
-import { t } from '@/i18n';
-import { getGroupModuleDevData, updateGroupModuleDevData } from '@/api';
+import { getDevStartStopStatus, getGroupModuleDevData, updateGroupModuleDevData } from '@/api';
 import { isNotEmptyVal } from '@/utils';
-import { DevParamChillerUnit, DevParamCoolingPump, DevParamCoolingTower } from '@/constants/device-params';
+import {
+  DevParamBypassValve,
+  DevParamChilledValve,
+  DevParamChillerUnit,
+  DevParamCommon,
+  DevParamCoolingTower,
+  DevParamCoolingValve,
+  DevParamInletValve,
+  DevParamOutletValve,
+} from '@/constants/device-params';
 
-import { DeviceType } from '../device-work-status/device-card';
+import { DeviceType, ValveType } from '../device-work-status/device-card';
 
-import type { EquipmentDetailsItem } from '@/types';
+import type { DevStartStopStatus, EquipmentDetailsItem, GroupModuleDevData, GroupModuleDevParam } from '@/types';
 
 interface Props {
   info?: EquipmentDetailsItem;
+  valveType?: number | string;
 }
 
 const props = defineProps<Props>();
@@ -28,64 +38,43 @@ defineEmits<{
 
 const { visible, showView, hideView } = useViewVisible();
 const { isLoading, handleRequest } = useRequest();
-const deviceRealTimeData = ref<Record<string, number | string | undefined>>({});
+const deviceData = ref<GroupModuleDevData>();
+const devStartStopStatus = ref<DevStartStopStatus>();
 let deviceRTDTimer: number | undefined;
 
-const deviceType = computed(() => {
-  return props.info?.deviceQueryVo.deviceType;
-});
-
-const disableStartStopCtrl = computed(() => {
-  const { isLocale, isAuto, isDisable } = getDeviceStatus();
-  return isLocale || isAuto || isDisable;
-});
-
-const startStopTip = computed(() => {
-  const { isLocale, isAuto, isDisable } = getDeviceStatus();
-  const tips: string[] = [];
-
-  if (isLocale) {
-    tips.push(t('realTimeMonitor.startStopControlTipLocal'));
+const monitorParams = computed<GroupModuleDevParam[]>(() => {
+  if (!deviceData.value?.dataListRO.length) {
+    return [];
   }
 
-  if (isAuto) {
-    tips.push(t('realTimeMonitor.startStopControlTipAuto'));
-  }
+  return sortDeviceParam(deviceData.value.dataListRO);
+});
 
-  if (isDisable) {
-    tips.push(t('realTimeMonitor.startStopControlTipDisable'));
+const controlParams = computed<GroupModuleDevParam[]>(() => {
+  if (!deviceData.value?.dataListRW.length) {
+    return [];
   }
 
-  let tipText = '';
-
-  tips.forEach((item, index) => {
-    tipText += `${index + 1}. ${item};\n`;
-  });
-
-  return tipText;
+  return sortDeviceParam(deviceData.value.dataListRW);
 });
 
-const getDeviceStatus = () => {
-  const { localRemoteStatus, manualAutoStatus, disableEnableStatus } = deviceRealTimeData.value;
-
-  return {
-    isLocale: localRemoteStatus === '本地',
-    isAuto: manualAutoStatus === 1,
-    isDisable: disableEnableStatus === 0,
-  };
-};
+const deviceType = computed(() => {
+  return props.info?.deviceQueryVo.deviceType;
+});
 
 watch(visible, () => {
   if (visible.value) {
     getDeviceData();
   } else {
-    deviceRealTimeData.value = {};
+    deviceData.value = undefined;
+    devStartStopStatus.value = undefined;
     clearTimeout(deviceRTDTimer);
   }
 });
 
 onUnmounted(() => {
-  deviceRealTimeData.value = {};
+  deviceData.value = undefined;
+  devStartStopStatus.value = undefined;
   clearTimeout(deviceRTDTimer);
 });
 
@@ -98,14 +87,17 @@ const getDeviceData = () => {
     }
 
     const { id, deviceType } = props.info.deviceQueryVo;
-    const data = await getGroupModuleDevData(id, deviceType);
 
-    data.dataList.forEach((item) => {
-      deviceRealTimeData.value[item.dataCode] = item.value;
-    });
+    if (props.valveType) {
+      deviceData.value = await getGroupModuleDevData(id, DeviceType.阀门, props.valveType as number);
+      devStartStopStatus.value = await getDevStartStopStatus(id, DeviceType.阀门, props.valveType as number);
+    } else {
+      deviceData.value = await getGroupModuleDevData(id, deviceType);
+      devStartStopStatus.value = await getDevStartStopStatus(id, deviceType);
+    }
   });
 
-  deviceRTDTimer = window.setTimeout(getDeviceData, 3000);
+  deviceRTDTimer = window.setTimeout(getDeviceData, 10000);
 };
 
 const updateDeviceData = (paramCode: string, value?: string | number | null) => {
@@ -122,55 +114,187 @@ const updateDeviceData = (paramCode: string, value?: string | number | null) =>
   });
 };
 
-const handleDisableEnableSwitch = () => {
-  const { disableEnableStatus } = deviceRealTimeData.value;
-  const title = disableEnableStatus ? t('common.disable') : t('common.enable');
-  const value = disableEnableStatus ? 0 : 1;
-
-  Modal.confirm({
-    title: t('realTimeMonitor.confirmSwitchToMode', { mode: title }),
-    closable: true,
-    centered: true,
-    onOk() {
-      updateDeviceData('disableEnableStatus', value);
-    },
-  });
+const getDeviceParamName = (param: GroupModuleDevParam, showUnit: boolean = false) => {
+  const { dataName } = param;
+  const unit = showUnit && param.unit ? `(${param.unit})` : '';
+
+  if (dataName.includes('开到位信号')) {
+    return '开到位信号';
+  }
+
+  if (dataName.includes('关到位信号')) {
+    return '关到位信号';
+  }
+
+  if (dataName.includes('本地远程状态')) {
+    return '本地/远程';
+  }
+
+  if (dataName.includes('开关指令')) {
+    return '开关控制';
+  }
+
+  if (dataName.includes('开度反馈')) {
+    return '开度反馈';
+  }
+
+  if (dataName.includes('开度最终设定')) {
+    return '开度最终设定';
+  }
+
+  if (dataName.includes('压差设定')) {
+    return '压差设定' + unit;
+  }
+
+  if (dataName.includes('开度上限设定')) {
+    return '开度上限设定' + unit;
+  }
+
+  if (dataName.includes('开度下限设定')) {
+    return '开度下限设定' + unit;
+  }
+
+  if (dataName.includes('开度手动设定')) {
+    return '开度设定' + unit;
+  }
+
+  if (dataName.includes('开度控制模式')) {
+    return '开度控制模式';
+  }
+
+  if (dataName.endsWith('冷冻水出水温度')) {
+    return '冷冻水出水温度';
+  }
+
+  if (dataName.includes('运行时间')) {
+    return '累计运行时间';
+  }
+
+  if (dataName.includes('禁启用状态')) {
+    return '启用/禁用';
+  }
+
+  if (dataName.includes('手自动状态')) {
+    return '自动/手动';
+  }
+
+  if (dataName.includes('手动启停')) {
+    return '启停控制';
+  }
+
+  return dataName + unit;
 };
 
-const handleAutoManualSwitch = () => {
-  const { manualAutoStatus } = deviceRealTimeData.value;
-  const title = manualAutoStatus ? t('common.manual') : t('common.automatic');
-  const content = manualAutoStatus
-    ? t('realTimeMonitor.confirmSwitchToManualTip')
-    : t('realTimeMonitor.confirmSwitchToAutoTip');
-  const value = manualAutoStatus ? 0 : 1;
-
-  Modal.confirm({
-    title: t('realTimeMonitor.confirmSwitchToMode', { mode: title }),
-    content,
-    closable: true,
-    centered: true,
-    onOk() {
-      updateDeviceData('manualAutoStatus', value);
-    },
-  });
+const getDeviceParamUnit = (param: GroupModuleDevParam) => {
+  const { unit } = param;
+
+  if (unit?.includes('本地/远程')) {
+    return '';
+  }
+
+  return unit;
 };
 
-const handleStartStopSwitch = () => {
-  const { startStopOrder } = deviceRealTimeData.value;
-  const title = startStopOrder ? t('common.confirmClose') : t('common.confirmOpen');
-  const value = startStopOrder ? 0 : 1;
-
-  Modal.confirm({
-    title: title + props.info?.deviceQueryVo.deviceName,
-    closable: true,
-    centered: true,
-    onOk() {
-      updateDeviceData('startStopOrder', value);
-    },
+const sortDeviceParam = (paramList: GroupModuleDevParam[]) => {
+  const paramOrder = getParamOrder();
+
+  return paramList.sort((a, b) => {
+    const indexA = paramOrder.indexOf(a.dataCode);
+    const indexB = paramOrder.indexOf(b.dataCode);
+
+    // 如果不在指定顺序中,将其放在末尾
+    if (indexA === -1) return 1;
+    if (indexB === -1) return -1;
+
+    return indexA - indexB;
   });
 };
 
+const getParamOrder = (): string[] => {
+  if (props.valveType) {
+    switch (props.valveType) {
+      case ValveType.冷冻侧阀:
+        return [
+          DevParamChilledValve.冷冻侧阀开到位信号,
+          DevParamChilledValve.冷冻侧阀关到位信号,
+          DevParamChilledValve.冷冻侧阀本地远程状态,
+          DevParamChilledValve.冷冻侧阀手自动状态,
+          DevParamChilledValve.冷冻侧阀开关指令,
+        ];
+      case ValveType.冷却侧阀:
+        return [
+          DevParamCoolingValve.冷却侧阀开到位信号,
+          DevParamCoolingValve.冷却侧阀关到位信号,
+          DevParamCoolingValve.冷却侧阀本地远程状态,
+          DevParamCoolingValve.冷却侧阀手自动状态,
+          DevParamCoolingValve.冷却侧阀开关指令,
+        ];
+      case ValveType.进口阀:
+        return [
+          DevParamInletValve.进口阀开到位信号,
+          DevParamInletValve.进口阀关到位信号,
+          DevParamInletValve.进口阀本地远程状态,
+          DevParamInletValve.进口阀手自动状态,
+          DevParamInletValve.进口阀开关指令,
+        ];
+      case ValveType.出口阀:
+        return [
+          DevParamOutletValve.出口阀开到位信号,
+          DevParamOutletValve.出口阀关到位信号,
+          DevParamOutletValve.出口阀本地远程状态,
+          DevParamOutletValve.出口阀手自动状态,
+          DevParamOutletValve.出口阀开关指令,
+        ];
+      case ValveType.旁通阀:
+        return [
+          DevParamBypassValve.旁通阀开度反馈,
+          DevParamBypassValve.旁通阀开度控制模式,
+          DevParamBypassValve.旁通阀开度手动设定,
+          DevParamBypassValve.旁通阀压差设定,
+          DevParamBypassValve.旁通阀开度上限设定,
+          DevParamBypassValve.旁通阀开度下限设定,
+        ];
+      default:
+        return [];
+    }
+  }
+
+  switch (props.info?.deviceQueryVo.deviceType) {
+    case DeviceType.冷水主机:
+      return [
+        DevParamChillerUnit.本地远程状态,
+        DevParamChillerUnit.冷冻水出水温度,
+        DevParamChillerUnit.有功功率,
+        DevParamChillerUnit.负载率,
+        DevParamChillerUnit.运行时间,
+        DevParamCommon.禁启用状态,
+        DevParamCommon.手自动状态,
+        DevParamCommon.手动启停,
+        DevParamChillerUnit.冷冻水出水温度设定值,
+        DevParamChillerUnit.负载率限制设定值,
+      ];
+    case DeviceType.冷却塔:
+    case DeviceType.冷却泵:
+    case DeviceType.冷冻泵:
+      return [
+        DevParamCoolingTower.本地远程状态,
+        DevParamCoolingTower.有功功率,
+        DevParamCoolingTower.频率反馈,
+        DevParamCoolingTower.运行时间,
+        DevParamCommon.禁启用状态,
+        DevParamCommon.手自动状态,
+        DevParamCommon.手动启停,
+        DevParamCommon.频率控制模式,
+      ];
+    default:
+      return [];
+  }
+};
+
+const isParamSwitch = (param: GroupModuleDevParam) => {
+  return param.bitAddress0Detail && param.bitAddress0Status && param.bitAddress1Detail && param.bitAddress1Status;
+};
+
 const router = useRouter();
 const { exit } = useFullscreen();
 
@@ -210,117 +334,37 @@ defineExpose({
   >
     <template #title>
       <div class="dev-ctrl-modal-header">
-        <span>{{ info?.deviceQueryVo.deviceName }}</span>
-        <span class="dev-ctrl-modal-operate" @click="goDevWorkStatus">
+        <span>{{ deviceData?.deviceName }}</span>
+        <span v-show="deviceData" class="dev-ctrl-modal-operate" @click="goDevWorkStatus">
           {{ $t('common.viewMore') }}
           <SvgIcon name="right" />
         </span>
       </div>
     </template>
-    <template v-if="deviceType === DeviceType.冷水主机">
-      <div class="dev-ctrl-modal-item">
-        <span>{{ $t('realTimeMonitor.chilledWaterOutletTemperature') }}</span>
-        <span>{{ deviceRealTimeData[DevParamChillerUnit.冷冻水出水温度] ?? '-' }}℃</span>
-      </div>
-      <div class="dev-ctrl-modal-item">
-        <span>{{ $t('realTimeMonitor.loadRate') }}</span>
-        <span>{{ deviceRealTimeData[DevParamChillerUnit.负载率] ?? '-' }}%</span>
-      </div>
-      <div class="dev-ctrl-modal-item">
-        <span>{{ $t('realTimeMonitor.activePower') }}</span>
-        <span>{{ deviceRealTimeData[DevParamChillerUnit.有功功率] ?? '-' }}kW</span>
-      </div>
-    </template>
-    <template v-if="deviceType === DeviceType.冷却塔">
-      <div class="dev-ctrl-modal-item">
-        <span>{{ $t('realTimeMonitor.localRemoteStatus') }}</span>
-        <span>{{ deviceRealTimeData[DevParamCoolingTower.本地远程状态] ?? '-' }}</span>
-      </div>
-      <div class="dev-ctrl-modal-item">
-        <span>{{ $t('realTimeMonitor.activePower') }}</span>
-        <span>{{ deviceRealTimeData[DevParamCoolingTower.有功功率] ?? '-' }}kW</span>
-      </div>
-      <div class="dev-ctrl-modal-item">
-        <span>{{ $t('realTimeMonitor.runningTime') }}</span>
-        <span>{{ deviceRealTimeData[DevParamCoolingTower.运行时间] ?? '-' }}{{ $t('common.hour') }}</span>
-      </div>
-    </template>
-    <template v-if="deviceType === DeviceType.冷冻泵 || deviceType === DeviceType.冷却泵">
-      <div class="dev-ctrl-modal-item">
-        <span>{{ $t('realTimeMonitor.localRemoteStatus') }}</span>
-        <span>{{ deviceRealTimeData[DevParamCoolingPump.本地远程状态] ?? '-' }}</span>
-      </div>
-      <div class="dev-ctrl-modal-item">
-        <span>{{ $t('realTimeMonitor.activePower') }}</span>
-        <span>{{ deviceRealTimeData[DevParamCoolingPump.有功功率] ?? '-' }}kW</span>
-      </div>
-      <div class="dev-ctrl-modal-item">
-        <span>{{ $t('realTimeMonitor.runningTime') }}</span>
-        <span>{{ deviceRealTimeData[DevParamCoolingPump.运行时间] ?? '-' }}{{ $t('common.hour') }}</span>
-      </div>
-    </template>
-    <div class="dev-ctrl-modal-separator"></div>
-    <div class="dev-ctrl-modal-item">
+    <AEmpty v-show="!monitorParams.length && !controlParams.length" />
+    <div class="dev-ctrl-modal-item" v-for="item in monitorParams" :key="item.dataCode">
+      <span>{{ getDeviceParamName(item) }}</span>
+      <span>{{ item.value || '-' }}{{ getDeviceParamUnit(item) }}</span>
+    </div>
+    <div v-show="monitorParams.length && controlParams.length" class="dev-ctrl-modal-separator"></div>
+    <!-- <div class="dev-ctrl-modal-item">
       <span></span>
       <span class="dev-ctrl-modal-operate" @click="$emit('openDevBatchExe')">
         {{ $t('common.batchExecution') }}
         <SvgIcon name="right" />
       </span>
-    </div>
-    <div class="dev-ctrl-modal-item">
-      <span>{{ $t('realTimeMonitor.enableDisable') }}</span>
-      <ASwitch
-        :checked="deviceRealTimeData.disableEnableStatus"
-        :checked-value="1"
-        :un-checked-value="0"
-        @click="handleDisableEnableSwitch"
-      />
-    </div>
-    <div class="dev-ctrl-modal-item">
-      <span>{{ $t('realTimeMonitor.autoManual') }}</span>
-      <ASwitch
-        :checked="deviceRealTimeData.manualAutoStatus"
-        :checked-value="1"
-        :un-checked-value="0"
-        @click="handleAutoManualSwitch"
+    </div> -->
+    <div class="dev-ctrl-modal-item" v-for="item in controlParams" :key="item.dataCode">
+      <span>{{ getDeviceParamName(item, true) }}</span>
+      <BitSwitchConfirm
+        v-if="isParamSwitch(item)"
+        :info="item"
+        :device-type="deviceType"
+        :start-stop-status="devStartStopStatus"
+        @ok="updateDeviceData(item.dataCode, $event)"
       />
+      <InputSave v-else :info="item" width="120px" @ok="updateDeviceData(item.dataCode, $event)" />
     </div>
-    <div class="dev-ctrl-modal-item">
-      <span>{{ $t('realTimeMonitor.startStopControl') }}</span>
-      <span class="dev-ctrl-modal-start-stop-right">
-        <ATooltip overlay-class-name="hvac-tooltip">
-          <template #title>{{ startStopTip }}</template>
-          <SvgIcon v-show="disableStartStopCtrl" name="info-cirlce-o" />
-        </ATooltip>
-        <ASwitch
-          :checked="deviceRealTimeData.startStopOrder"
-          :checked-value="1"
-          :un-checked-value="0"
-          :disabled="disableStartStopCtrl"
-          @click="handleStartStopSwitch"
-        />
-      </span>
-    </div>
-    <template v-if="deviceType === DeviceType.冷水主机">
-      <div class="dev-ctrl-modal-item">
-        <span>{{ $t('realTimeMonitor.chilledWaterOutletSetValue') }}</span>
-        <AInputNumber
-          class="dev-ctrl-chiller-input"
-          v-model:value="deviceRealTimeData[DevParamChillerUnit.冷冻水出水温度设定值]"
-          :controls="false"
-          @change="updateDeviceData(DevParamChillerUnit.冷冻水出水温度设定值, $event)"
-        />
-      </div>
-      <div class="dev-ctrl-modal-item">
-        <span>{{ $t('realTimeMonitor.loadRateLimitSetValue') }}</span>
-        <AInputNumber
-          class="dev-ctrl-chiller-input"
-          v-model:value="deviceRealTimeData[DevParamChillerUnit.负载率限制设定值]"
-          :controls="false"
-          @change="updateDeviceData(DevParamChillerUnit.负载率限制设定值, $event)"
-        />
-      </div>
-    </template>
     <ASpin v-if="isLoading" class="center-loading" :spinning="true" />
   </AModal>
 </template>
@@ -375,19 +419,4 @@ defineExpose({
     font-size: 12px;
   }
 }
-
-.dev-ctrl-modal-start-stop-right {
-  display: flex;
-  align-items: center;
-
-  i {
-    margin-right: 8px;
-    font-size: 12px;
-    color: #999;
-  }
-}
-
-.dev-ctrl-chiller-input {
-  width: 120px;
-}
 </style>

+ 12 - 4
src/views/real-time-monitor/RealTimeMonitor.vue

@@ -11,7 +11,7 @@ import { t } from '@/i18n';
 import { equipmentDetails, getGroupModuleInfo, getPageList, noPaginationDevicesList } from '@/api';
 import { VisualModuleType } from '@/constants';
 
-import { DeviceType } from '../device-work-status/device-card';
+import { DeviceType, ValveType } from '../device-work-status/device-card';
 
 import DeviceControl from './device-control/DeviceControl.vue';
 import DeviceBatchExe from './DeviceBatchExe.vue';
@@ -40,6 +40,7 @@ const { renderView, refreshView } = useRefreshView();
 const moduleInfo = ref<GroupModuleInfo>();
 const deviceList = ref<DeviceGroupTree[]>([]);
 const deviceInfo = ref<EquipmentDetailsItem>();
+const deviceValveType = ref<number | string>();
 
 onMounted(() => {
   refreshView();
@@ -119,7 +120,7 @@ const openEditor = () => {
 
 const ctrlDeviceTypes = [DeviceType.冷水主机, DeviceType.冷却塔, DeviceType.冷却泵, DeviceType.冷冻泵];
 
-const openDevCtrlModal = (id: number) => {
+const openDevCtrlModal = (id: number, valveType: number) => {
   if (!id) {
     // message.error(t('realTimeMonitor.unboundDevice'));
     return;
@@ -128,9 +129,11 @@ const openDevCtrlModal = (id: number) => {
   handleRequest(async () => {
     const data = await equipmentDetails(id);
     const { deviceQueryVo } = data;
+    const isBypassValve = valveType === ValveType.旁通阀 && deviceQueryVo?.deviceType === DeviceType.控制柜;
 
-    if (deviceQueryVo && ctrlDeviceTypes.includes(deviceQueryVo.deviceType)) {
+    if (deviceQueryVo && (ctrlDeviceTypes.includes(deviceQueryVo.deviceType) || isBypassValve)) {
       deviceInfo.value = data;
+      deviceValveType.value = valveType;
       deviceCtrlModalRef.value?.showView();
     }
   });
@@ -182,7 +185,12 @@ defineExpose({
       <Visual2DEditor ref="visual2DEditor" :info="moduleInfo" :device-list="deviceList" @close="refreshView" />
       <DeviceControl ref="deviceControl" :info="moduleInfo" />
     </template>
-    <DeviceCtrlModal ref="deviceCtrlModal" :info="deviceInfo" @open-dev-batch-exe="deviceBatchExeRef?.showView" />
+    <DeviceCtrlModal
+      ref="deviceCtrlModal"
+      :info="deviceInfo"
+      :valve-type="deviceValveType"
+      @open-dev-batch-exe="deviceBatchExeRef?.showView"
+    />
     <DeviceBatchExe ref="deviceBatchExe" :group-id="props.deviceGroupId" />
     <ASpin v-if="isLoading" class="center-loading" :spinning="true" />
   </div>