import { useState, useEffect } from 'react' import { Select } from 'antd' import { Column } from './Column' import { CustomColumn } from './CustomColumn' import ActiveMessagesOnline from './ActiveMessagesOnline' import { ModeDisplay } from './ModeDisplay' import { UserOfWell } from './UserOfWells' import LoaderPortal from '../../components/LoaderPortal' import { Grid, GridItem, Flex } from '../../components/Grid' import { Subscribe } from '../../services/signalr' import { DrillFlowChartService, TelemetryDataSaubService, TelemetryDataSpinService, WellService } from '../../services/api' import { invokeWebApiWrapperAsync } from '../../components/factory' import MomentStabPicEnabled from '../../images/DempherOn.png' import MomentStabPicDisabled from '../../images/DempherOff.png' import SpinPicEnabled from '../../images/SpinEnabled.png' import SpinPicDisabled from '../../images/SpinDisabled.png' import '../../styles/message.css' const { Option } = Select const dash = [7, 3] const blockHeightGroup = [ { label: 'Высота блока', units: 'м', xAccessorName: 'blockPosition', yAccessorName: 'date', color: '#333', showLabels: true }, { label: 'wellDepth', units: 'м', xAccessorName: 'wellDepth', yAccessorName: 'date', color: '#333', showLine: false, xConstValue: 30, dash }, { label: 'Расход', units: 'л/c', xAccessorName: 'flow', yAccessorName: 'date', color: '#077', showLabels: true, showLine: true }, { label: 'flowLimits', units: 'л/с', xAccessorName: 'flow', yAccessorName: 'date', color: 'rgba(0,119,119,.1)', isShape: true } ] const blockSpeedGroup = [ { label: 'Скорость блока', units: 'м/ч', xAccessorName: 'blockSpeed', yAccessorName: 'date', color: '#0a0', showLabels: true, }, { label: 'blockSpeedSp', units: 'м/ч', xAccessorName: 'blockSpeedSp', yAccessorName: 'date', color: '#0a0', footer: 'SP', dash } ] const pressureGroup = [ { label: 'Давление', units: 'атм', xAccessorName: 'pressure', yAccessorName: 'date', color: '#c00', showLabels: true }, { label: 'pressureSp', units: 'атм', xAccessorName: 'pressureSp', yAccessorName: 'date', color: '#c00', footer: 'SP', dash }, { label: 'pressureIdle', units: 'атм', xAccessorName: 'pressureIdle', yAccessorName: 'date', color: '#c00', footer: 'IDLE', dash }, { label: 'pressureDeltaLimitMax', units: 'атм', xAccessorName: 'pressureDeltaLimitMax', yAccessorName: 'date', color: '#c00', footer: true, dash }, { label: 'pressureLimits', units: 'атм', xAccessorName: 'pressure', yAccessorName: 'date', color: 'rgba(204,0,0,.1)', isShape: true } ] const axialLoadGroup = [ { label: 'Осевая нагрузка', units: 'т', xAccessorName: 'axialLoad', yAccessorName: 'date', color: '#00a', showLabels: true }, { label: 'axialLoadSp', units: 'т', xAccessorName: 'axialLoadSp', yAccessorName: 'date', color: '#00a', footer: 'SP', dash }, { label: 'axialLoadLimitMax', units: 'т', xAccessorName: 'axialLoadLimitMax', yAccessorName: 'date', color: '#00a', footer: true, dash }, { label: 'axialLoadLimits', units: 'т', xAccessorName: 'axialLoad', yAccessorName: 'date', color: 'rgba(0,0,170,.1)', isShape: true } ] const hookWeightGroup = [ { label: 'Вес на крюке', units: 'т', xAccessorName: 'hookWeight', yAccessorName: 'date', color: '#0aa', showLabels: true }, { label: 'hookWeightIdle', units: 'т', xAccessorName: 'hookWeightIdle', yAccessorName: 'date', color: '#0aa', footer: 'IDLE', dash }, { label: 'hookWeightLimitMin', units: 'т', xAccessorName: 'hookWeightLimitMin', yAccessorName: 'date', color: '#0aa', footer: true, dash }, { label: 'hookWeightLimitMax', units: 'т', xAccessorName: 'hookWeightLimitMax', yAccessorName: 'date', color: '#0aa', footer: true, dash }, { label: 'Обороты ротора', units: 'об/мин', xAccessorName: 'rotorSpeed', yAccessorName: 'date', color: '#aa0', showLabels: true }, { label: 'rotorSpeedLimits', units: 'об/мин', xAccessorName: 'rotorSpeed', yAccessorName: 'date', color: 'rgba(170,170,0,.1)', isShape: true } ] const rotorTorqueGroup = [ { label: 'Момент на роторе', units: 'кН·м', xAccessorName: 'rotorTorque', yAccessorName: 'date', color: '#a0a', showLabels: true }, { label: 'План. Момент на роторе', units: 'кН·м', xAccessorName: 'rotorTorqueSp', yAccessorName: 'date', color: '#a0a', footer: 'SP', dash }, { label: 'Момент на роторе х.х.', units: 'кН·м', xAccessorName: 'rotorTorqueIdle', yAccessorName: 'date', color: '#a0a', footer: 'IDLE', dash }, { label: 'rotorTorqueLimitMax', units: 'кН·м', xAccessorName: 'rotorTorqueLimitMax', yAccessorName: 'date', color: '#a0a', footer: true, dash }, { label: 'rotorTorqueLimits', units: 'кН·м', xAccessorName: 'rotorTorque', yAccessorName: 'date', color: 'rgba(170,0,170,.1)', isShape: true } ] const paramsGroups = [blockHeightGroup, blockSpeedGroup, pressureGroup, axialLoadGroup, hookWeightGroup, rotorTorqueGroup] const timePeriodCollection = [ { value: '60', label: '1 минута' }, { value: '300', label: '5 минут' }, { value: '600', label: '10 минут' }, { value: '1800', label: '30 минут' }, { value: '3600', label: '1 час' }, { value: '21600', label: '6 часов' }, { value: '43200', label: '12 часов' }, { value: '86400', label: '24 часа' } ] const defaultChartInterval = '600' const getLast = (data) => Array.isArray(data) ? data.slice(-1)[0] : data const isMseEnabled = (dataSaub) => { const lastData = getLast(dataSaub) return (lastData?.mseState && 2) > 0 } const isTorqueStabEnabled = (dataSpin) => { const lastData = getLast(dataSpin) return lastData?.state === 7 } const isSpinEnabled = (dataSpin) => { const lastData = getLast(dataSpin) return lastData?.state > 0 && lastData?.state !== 6 } const getIndexOfDrillingBy = (dataSaub) => { const order = { 0: -1, 1: 1, // скорость 2: 2, // давление 3: 3, // нагрузка 4: 5, // момент } const idFeedRegulator = getLast(dataSaub)?.idFeedRegulator ?? 0 return order[idFeedRegulator] ?? -1 } export default function TelemetryView({ idWell }) { const [dataSaub, setDataSaub] = useState([]) const [dataSpin, setDataSpin] = useState([]) const [chartInterval, setChartInterval] = useState(defaultChartInterval) const [wellData, setWellData] = useState({ idState: 0 }) const [showLoader, setShowLoader] = useState(false) const [flowChartData, setFlowChartData] = useState([]) const options = timePeriodCollection.map((line) => {line.label}) const handleDataSaub = (data) => { if (data) { data.forEach((_, idx) => { if (data[idx].rotorSpeed < 1) data[idx].rotorSpeed = 0; if (data[idx].rotorTorque < 1) data[idx].rotorTorque = 0; data[idx].blockSpeed = Math.abs(data[idx].blockSpeed) }) setDataSaub(data) } } const handleDataSpin = (data) => { if (data) { setDataSpin(data) } } useEffect(() => { const unsubscribeSaub = Subscribe('hubs/telemetry', 'ReceiveDataSaub', `well_${idWell}`, handleDataSaub) const unsubscribeSpin = Subscribe('hubs/telemetry', 'ReceiveDataSpin', `well_${idWell}`, handleDataSpin) invokeWebApiWrapperAsync( async () => { const flowChart = await DrillFlowChartService.get(idWell) const dataSaub = await TelemetryDataSaubService.getData(idWell, null, chartInterval) const dataSpin = await TelemetryDataSpinService.getData(idWell, null, chartInterval) setFlowChartData(flowChart ?? []) handleDataSaub(dataSaub) handleDataSpin(dataSpin) }, null, `Не удалось получить данные по скважине "${idWell}"`, ) return () => { unsubscribeSaub() unsubscribeSpin() } }, [idWell, chartInterval]) useEffect(() => invokeWebApiWrapperAsync( async () => { const well = await WellService.get(idWell) setWellData(well ?? {}) }, setShowLoader, `Не удалось загрузить данные по скважине "${idWell}"` ), [idWell]) const onStatusChanged = (value) => { invokeWebApiWrapperAsync( async () => { const well = { ...wellData, idState: value } await WellService.updateWell(idWell, well) setWellData(well) }, setShowLoader, `Не удалось задать состояние скважины "${idWell}"` ) } return ( Интервал: {options} Статус: Неизвестно В работе Завершено MSE {paramsGroups.map((group, index) => )} ) }