asb_cloud_front/src/pages/TelemetryView/index.jsx

344 lines
9.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 { TelemetryDataSaubService, TelemetryDataSpinService } 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',
showGraph: true
}, {
label: 'wellDepth',
units: 'м',
xAccessorName: 'wellDepth',
yAccessorName: 'date',
color: '#333',
showLine: false,
xConstValue: 30,
dash
}, {
label: 'Расход',
units: 'м³/ч',
xAccessorName: 'flow',
yAccessorName: 'date',
color: '#077',
showGraph: true
}
]
const blockSpeedGroup = [
{
label: 'Скорость блока',
units: 'м/ч',
xAccessorName: 'blockSpeed',
yAccessorName: 'date',
color: '#0a0',
showGraph: true
}, {
label: 'blockSpeedSp',
units: 'м/ч',
xAccessorName: 'blockSpeedSp',
yAccessorName: 'date',
color: '#0a0',
footer: 'SP',
dash
}
]
const pressureGroup = [
{
label: 'Давление',
units: 'атм',
xAccessorName: 'pressure',
yAccessorName: 'date',
color: '#c00',
showGraph: 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
}
]
const axialLoadGroup = [
{
label: 'Осевая нагрузка',
units: 'т',
xAccessorName: 'axialLoad',
yAccessorName: 'date',
color: '#00a',
showGraph: 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
},
]
const hookWeightGroup = [
{
label: 'Вес на крюке',
units: 'т',
xAccessorName: 'hookWeight',
yAccessorName: 'date',
color: '#0aa',
showGraph: 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',
showGraph: true
}
]
const rotorTorqueGroup = [
{
label: 'Момент на роторе',
units: 'кН·м',
xAccessorName: 'rotorTorque',
yAccessorName: 'date',
color: '#a0a',
showGraph: 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
},
]
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 [showLoader, setShowLoader] = useState(false)
const options = timePeriodCollection.map((line) => <Option key={line.value}>{line.label}</Option>)
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(() => {
invokeWebApiWrapperAsync(
async () => {
const dataSaub = await TelemetryDataSaubService.getData(idWell, null, chartInterval)
const dataSpin = await TelemetryDataSpinService.getData(idWell, null, chartInterval)
handleDataSaub(dataSaub)
handleDataSpin(dataSpin)
},
setShowLoader,
`Не удалось получить данные по скважине "${idWell}"`,
)
const unsubscribeSaub = Subscribe('hubs/telemetry', 'ReceiveDataSaub', `well_${idWell}`, handleDataSaub)
const unsubscribeSpin = Subscribe('hubs/telemetry', 'ReceiveDataSpin', `well_${idWell}`, handleDataSpin)
return () => {
unsubscribeSaub()
unsubscribeSpin()
}
}, [idWell, chartInterval])
return (
<LoaderPortal show={showLoader}>
<Grid style={{ gridTemplateColumns: 'auto repeat(6, 1fr)' }}>
<GridItem col={'1'} row={'1'} colSpan={'8'} style={{ marginBottom: '0.5rem' }}>
<Flex>
<ModeDisplay data={dataSaub} />
<div style={{ marginLeft: '1rem' }}>
Интервал:&nbsp;
<Select defaultValue={defaultChartInterval} onChange={setChartInterval}>
{options}
</Select>
</div>
<span style={{ flexGrow: 20 }}>&nbsp;</span>
<img src={isTorqueStabEnabled(dataSpin) ? MomentStabPicEnabled : MomentStabPicDisabled} style={{ marginRight: '15px' }} alt={'TorqueMaster'} />
<img src={isSpinEnabled(dataSpin) ? SpinPicEnabled : SpinPicDisabled} style={{ marginRight: '15px' }} alt={'SpinMaster'} />
<h2 style={{ marginBottom: 0, marginRight: '15px', fontWeight: 'bold', color: isMseEnabled(dataSaub) ? 'green' : 'lightgrey' }}>MSE</h2>
<UserOfWell data={dataSaub} />
</Flex>
</GridItem>
<GridItem col={'1'} row={'2'} rowSpan={'3'} style={{ minWidth: '260px', width: '0.142fr' }}>
<CustomColumn data={dataSaub} />
</GridItem>
{paramsGroups.map((group, index) =>
<GridItem col={2 + index} row={'2'} className={'border_small'} key={`${group.label}${index}`}>
<Column
style={{ width: '13vw' }}
data={dataSaub}
lineGroup={group}
interval={chartInterval}
headerHeight={'60px'}
showBorder={getIndexOfDrillingBy(dataSaub) === index} />
</GridItem>
)}
<GridItem col={'2'} row={'3'} colSpan={'7'}>
<ActiveMessagesOnline idWell={idWell} />
</GridItem>
</Grid>
</LoaderPortal>
)
}