asb_cloud_front/src/pages/TelemetryView/index.jsx
Фролов c818d9fde1 design
2021-10-27 14:19:57 +05:00

418 lines
11 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 {
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) => <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(() => {
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 (
<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>
<div style={{ marginLeft: '1rem' }}>
Статус:&nbsp;
<Select value={wellData.idState ?? 0} onChange={onStatusChanged}>
<Option value={0} disabled>Неизвестно</Option>
<Option value={1}>В работе</Option>
<Option value={2}>Завершено</Option>
</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}`} style={{padding:0}}>
<Column
style={{ width: '13vw' }}
data={dataSaub}
flowChartData={flowChartData}
lineGroup={group}
interval={chartInterval}
headerHeight={'60px'}
showBorder={getIndexOfDrillingBy(dataSaub) === index} />
</GridItem>
)}
<GridItem col={'2'} row={'3'} colSpan={'7'}>
<ActiveMessagesOnline idWell={idWell} />
</GridItem>
</Grid>
</LoaderPortal>
)
}