asb_cloud_front/src/pages/TelemetryView.jsx

238 lines
8.1 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 { useParams } from 'react-router-dom'
import {Row, Col, Select, Table} from 'antd'
import { ChartTimeOnline } from '../components/charts/ChartTimeOnline'
import Loader from '../components/Loader'
import { ChartTimeOnlineFooter } from '../components/ChartTimeOnlineFooter'
import { CustomColumn } from '../components/CustomColumn'
import { UserOfWells } from '../components/UserOfWells'
import { ModeDisplay } from '../components/ModeDisplay'
import { Display } from '../components/Display'
import notify from '../components/Notification'
import moment from 'moment'
import { Subscribe } from '../services/signalr'
import { DataService, MessageService } from '../services/api'
import '../styles/message.css'
import Notification from "../components/Notification";
const { Option } = Select
const dash = [7, 3]
const blockHeightGroup = {
label: "Высота блока",
yDisplay: false,
linePv: { label: "blockHeight", units: 'м', xAccessorName: "blockHeight", yAccessorName: "date", color: '#333' },
}
const blockSpeedGroup = {
label: "Скорость блока",
yDisplay: false,
linePv: { label: "blockSpeed", units: 'м/ч', xAccessorName: "blockSpeed", yAccessorName: "date", color: '#0a0' },
lineSp: { label: "blockSpeedSp", units: 'м/ч', xAccessorName: "blockSpeedSp", yAccessorName: "date", color: '#0a0' },
}
const pressureGroup = {
label: "Давление",
yDisplay: false,
linePv: { label: "pressure", units: 'атм', xAccessorName: "pressure", yAccessorName: "date", color: '#c00' },
lineSp: { label: "pressureSp", units: 'атм', xAccessorName: "pressureSp", yAccessorName: "date", color: '#c00' },
lineIdle: { label: "pressureIdle", units: 'атм', xAccessorName: "pressureIdle", yAccessorName: "date", color: '#c00' },
linesOther: [
{ label: "мекс. перепад", units: 'атм', xAccessorName: "pressureDeltaLimitMax", yAccessorName: "date", color: '#c00' },
],
}
const axialLoadGroup = {
label: "Осевая нагрузка",
yDisplay: false,
linePv: { label: "axialLoad", units: 'т', xAccessorName: "axialLoad", yAccessorName: "date", color: '#00a' },
lineSp: { label: "axialLoadSp", units: 'т', xAccessorName: "axialLoadSp", yAccessorName: "date", color: '#00a', dash },
linesOther: [
{ label: "axialLoadLimitMax", units: 'т', xAccessorName: "axialLoadLimitMax", yAccessorName: "date", color: '#00a' },
],
}
const hookWeightGroup = {
label: "Ввес на крюке",
yDisplay: false,
linePv: { label: "hookWeight", units: 'т', xAccessorName: "hookWeight", yAccessorName: "date", color: '#0aa' },
lineIdle: { label: "hookWeightIdle", units: 'т', xAccessorName: "hookWeightIdle", yAccessorName: "date", color: '#0aa', dash },
linesOther: [
{ label: "hookWeightLimitMin", units: 'т', xAccessorName: "hookWeightLimitMin", yAccessorName: "date", color: '#0aa' },
{ label: "hookWeightLimitMax", units: 'т', xAccessorName: "hookWeightLimitMax", yAccessorName: "date", color: '#0aa' },
],
}
const rotorTorqueGroup = {
label: "Момент на роторе",
yDisplay: false,
linePv: { label: "rotorTorque", units: 'кН·м', xAccessorName: "rotorTorque", yAccessorName: "date", color: '#a0a' },
lineSp: { label: "rotorTorqueSp", units: 'кН·м', xAccessorName: "rotorTorqueSp", yAccessorName: "date", color: '#a0a' },
lineIdle: { label: "rotorTorqueIdle", units: 'кН·м', xAccessorName: "rotorTorqueIdle", yAccessorName: "date", color: '#a0a' },
linesOther: [
{ label: "rotorTorqueLimitMax", units: 'кН·м', xAccessorName: "rotorTorqueLimitMax", yAccessorName: "date", color: '#a0a' },
],
}
const paramsGroups = [blockHeightGroup, blockSpeedGroup, pressureGroup, axialLoadGroup, hookWeightGroup, rotorTorqueGroup]
export const Column = ({ lineGroup, data, interval }) => {
let lines = [lineGroup.linePv]
if (lineGroup.lineSp)
lines.push(lineGroup.lineSp)
let dataLast = null
let pv = null
if (data?.length > 0) {
dataLast = data[data.length - 1];
if (lineGroup.linePv)
pv = dataLast[lineGroup.linePv?.xAccessorName]
}
return (
<>
<Display
label={lineGroup.label}
value={pv}
suffix={lineGroup.linePv?.units} isArrowVisible={true}/>
<ChartTimeOnline
data={data}
yDisplay={lineGroup.yDisplay}
lines={lines}
interval={interval} />
<ChartTimeOnlineFooter
data={dataLast}
{...lineGroup} />
</>)
}
// Словарь категорий для строк таблицы
const categoryDictionary = {
1: { title: 'Авария' },
2: { title: 'Предупреждение' },
3: { title: 'Информация' },
}
// Конфигурация таблицы
const columns = [
{
title: 'Дата',
dataIndex: 'date',
render: (item) => moment(item).format('DD MMM YYYY, HH:MM:ss'),
sorter: (a, b) => new Date(b.date) - new Date(a.date),
sortDirections: ['descend', 'ascend'],
},
{
title: 'Категория',
dataIndex: 'categoryId',
render: (_, item) => categoryDictionary[item.categoryId].title,
style: (_, item) => categoryDictionary[item.categoryId].style,
sorter: (a, b) => a.categoryId - b.categoryId,
sortDirections: ['descend', 'ascend'],
},
{
title: 'Сообщение',
dataIndex: 'message',
onFilter: (value, record) => record.name.indexOf(value) === 0,
},
{
title: 'Пользователь',
dataIndex: 'user',
},
];
export default function TelemetryView(props) {
let { id } = useParams()
const [saubData, setSaubData] = useState([])
const [chartInterval, setChartInterval] = useState(600)
const [messages, setMessages] = useState([])
const [loader] = useState(false) // , setLoader
const handleReceiveDataSaub = (data) => {
if (data) {
setSaubData(data)
}
}
const handleReceiveMessages = (messages) => {
if (messages) {
setMessages(messages.items.splice(0, 4))
}
}
useEffect(() => {
try {
DataService.getData(id)
.then(handleReceiveDataSaub)
} catch (ex) {
Notification(`Не удалось загрузить данные по скважине ${id}`, 'error')
}
try {
MessageService.getMessage(id)
.then(handleReceiveMessages)
} catch (ex) {
Notification(`Не удалось загрузить сообщения по скважине ${id}`, 'error')
console.log(ex)
}
let unSubscribeDataSaubHub = Subscribe('ReceiveDataSaub', `well_${id}`, handleReceiveDataSaub)
let unSubscribeMessagesHub = Subscribe('ReceiveMessages', `well_${id}`, handleReceiveMessages)
return () => {
unSubscribeDataSaubHub()
unSubscribeMessagesHub()
}
}, [id]);
const colSpan = 24 / (paramsGroups.length)
return (<div>
<Row style={{ marginBottom: '1rem' }}>
<Col>
<ModeDisplay data={saubData} />
</Col>
<span style={{ flexGrow: 0.1 }}>&nbsp;</span>
<Col>
Интервал:&nbsp;
<Select defaultValue="600" onChange={setChartInterval}>
<Option value='600'>10 минут</Option>
<Option value='1800'>30 минут</Option>
<Option value='3600'>1 час</Option>
<Option value='21600'>6 час</Option>
<Option value='86400'>1 день</Option>
</Select>
</Col>
<span style={{ flexGrow: 1 }}>&nbsp;</span>
<Col>
<UserOfWells data={saubData}/>
</Col>
</Row>
<Row>
<Col span={2} >
<CustomColumn data={saubData} />
</Col>
<Col span={24 - 2}>
<Row>
{paramsGroups.map(group =>
<Col span={colSpan} className='border_small' key={group.label}>
<Column data={saubData} lineGroup={group} interval={chartInterval} />
</Col>)}
</Row>
</Col>
</Row>
<Table
showHeader={false}
columns={columns}
dataSource={messages}
rowClassName={(record) => `event_message_${record.categoryId} event_message`}
className={'message_table'}
size={'small'}
pagination={false}
rowKey={(record) => record.id}
/>
{loader && <Loader />}
</div>)
}