From f0e16032e0a33afb8fc02934851f23abdd621e6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A4=D1=80=D0=BE=D0=BB=D0=BE=D0=B2?= Date: Thu, 30 Sep 2021 11:42:23 +0500 Subject: [PATCH] Animate PidId border and icons: MSE, Spin, TorqueStab. Refactor TelemetryView Replace antd.Grid to own html5Grid. Fix RigMnemo bit animation. --- doc/MSE_and_torqueStab_info.txt | 4 +- package.json | 2 +- src/components/Grid.jsx | 21 +- .../TelemetryView/ActiveMessagesOnline.jsx | 4 +- src/pages/TelemetryView/Column.jsx | 6 +- src/pages/TelemetryView/CustomColumn.jsx | 6 +- src/pages/TelemetryView/RigMnemo.jsx | 99 +++++--- src/pages/TelemetryView/UserOfWells.jsx | 2 +- src/pages/TelemetryView/index.jsx | 133 ++++++---- src/pages/TelemetryView/index_backup.jsx | 238 ++++++++++++++++++ 10 files changed, 414 insertions(+), 101 deletions(-) create mode 100644 src/pages/TelemetryView/index_backup.jsx diff --git a/doc/MSE_and_torqueStab_info.txt b/doc/MSE_and_torqueStab_info.txt index 9fa7ad0..7950584 100644 --- a/doc/MSE_and_torqueStab_info.txt +++ b/doc/MSE_and_torqueStab_info.txt @@ -1,7 +1,7 @@ -Вопрос Олегу: Какой бит и в каком регистре (или значение регистра) контроллера спинмастера сигнализирует что система спинмастер активана/работает? +# Вопрос Олегу: Какой бит и в каком регистре (или значение регистра) контроллера спинмастера сигнализирует что система спинмастер активана/работает? Ответ: Такого бита нет, но можно понять если etap %MW1600: INT; не равен 6 и не равен 0 тогда система в работе -Вопрос Олегу: Какой бит и в каком регистре (или значение регистра) контроллера спинмастера сигнализирует что система стабилизации крутящего момента активна/работает? +# Вопрос Олегу: Какой бит и в каком регистре (или значение регистра) контроллера спинмастера сигнализирует что система стабилизации крутящего момента активна/работает? Ответ: Такого бита по сути тоже нет но можно понять что когда stik_sleep %MX2802.01: BOOL; =true и diff --git a/package.json b/package.json index 13399cb..576e207 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "react_test": "react-scripts test", "eject": "react-scripts eject" }, - "proxy": "http://192.168.1.58:5000", + "proxy": "http://192.168.1.70:5000", "eslintConfig": { "extends": [ "react-app", diff --git a/src/components/Grid.jsx b/src/components/Grid.jsx index 362bf76..177fc31 100644 --- a/src/components/Grid.jsx +++ b/src/components/Grid.jsx @@ -1,18 +1,18 @@ -export const Grid = ({children, ...other}) => { +export const Grid = ({children, style, ...other}) => { const gridContainerStyle = { display: 'grid', margin: '8px', justifyItems: 'stretch', alignItems: 'stretch', - ...other, + ...style, } - return
+ return
{children}
} -export const GridItem = ({children, row, col, rowSpan, colSpan, ...other}) => { +export const GridItem = ({children, row, col, rowSpan, colSpan, style, ...other}) => { const localRow = +row const localCol = +col const localColSpan = colSpan ? colSpan - 1 : 0 @@ -23,10 +23,17 @@ export const GridItem = ({children, row, col, rowSpan, colSpan, ...other}) => { gridRowStart: localRow, gridRowEnd: localRow + localRowSpan, padding: '4px', - ...other, + ...style, } - return
+ return
{children}
-} \ No newline at end of file +} + +export const Flex = ({children, style, ...other}) => +
+ {children} +
\ No newline at end of file diff --git a/src/pages/TelemetryView/ActiveMessagesOnline.jsx b/src/pages/TelemetryView/ActiveMessagesOnline.jsx index c613546..db7f8b7 100644 --- a/src/pages/TelemetryView/ActiveMessagesOnline.jsx +++ b/src/pages/TelemetryView/ActiveMessagesOnline.jsx @@ -34,8 +34,8 @@ const columns = [ { title: 'Категория', dataIndex: 'categoryId', - render: (_, item) => categoryDictionary[item.categoryId].title, - style: (_, item) => categoryDictionary[item.categoryId].style, + render: (_, item) => categoryDictionary[item.categoryId]?.title, + style: (_, item) => categoryDictionary[item.categoryId]?.style, sorter: (a, b) => a.categoryId - b.categoryId, sortDirections: ['descend', 'ascend'], }, diff --git a/src/pages/TelemetryView/Column.jsx b/src/pages/TelemetryView/Column.jsx index 75b2f0c..db97573 100644 --- a/src/pages/TelemetryView/Column.jsx +++ b/src/pages/TelemetryView/Column.jsx @@ -2,7 +2,7 @@ import {Display} from "../../components/Display"; import {ChartTimeOnline} from "./ChartTimeOnline"; import {ChartTimeOnlineFooter} from "./ChartTimeOnlineFooter"; -export const Column = ({lineGroup, data, interval, showBorder}) => { +export const Column = ({lineGroup, data, interval, showBorder, style}) => { let lines = [lineGroup.linePv] if (lineGroup.lineSp) @@ -26,7 +26,7 @@ export const Column = ({lineGroup, data, interval, showBorder}) => { } return ( - <> +
{ - ) +
) } \ No newline at end of file diff --git a/src/pages/TelemetryView/CustomColumn.jsx b/src/pages/TelemetryView/CustomColumn.jsx index ed90fce..4c996ca 100644 --- a/src/pages/TelemetryView/CustomColumn.jsx +++ b/src/pages/TelemetryView/CustomColumn.jsx @@ -28,7 +28,9 @@ export const CustomColumn = ({data}) => { format = {param.format} />)} + blockPosition={dataLast?.blockPosition??Number.NaN} + bitPosition={dataLast?.bitDepth??Number.NaN} + wellDepth={dataLast?.wellDepth??Number.NaN} + /> ) } \ No newline at end of file diff --git a/src/pages/TelemetryView/RigMnemo.jsx b/src/pages/TelemetryView/RigMnemo.jsx index 29f536d..fa9c036 100644 --- a/src/pages/TelemetryView/RigMnemo.jsx +++ b/src/pages/TelemetryView/RigMnemo.jsx @@ -39,35 +39,54 @@ const styleBlock = { fill: "#ffdd55", }; -const stylePump1 = { - ...styleBase, - fill: "#5fd35f", -}; +// const stylePump1 = { +// ...styleBase, +// fill: "#5fd35f", +// }; -const stylePump2 = { - ...styleBase, - fill: "#b3b3b3", -}; +// const stylePump2 = { +// ...styleBase, +// fill: "#b3b3b3", +// }; export default function RigMnemo({ blockPosition, bitPosition, + wellDepth }) { + let blockPositionY = 0 + let bitPositionY = 0 - let blockPositionLocal = +blockPosition - blockPositionLocal = blockPositionLocal ? blockPositionLocal : 0 - const blockTranslate = `translate(-75, ${-35 + (50 * (30 - blockPositionLocal) / 30)})` + const isBlockVisible = blockPosition != null && Number.isFinite(blockPosition) + const isBitVisible = wellDepth && bitPosition != null && Number.isFinite(bitPosition) && Number.isFinite(wellDepth) - //let bitPositionLocal = +bitPosition - //bitPositionLocal = bitPositionLocal ? bitPositionLocal : 0 - //const bitTranslate = `translate(0, ${-41 + 41 * (3426 - bitPosition)/(3426 - 3200)})` - const bitTranslate = `translate(0, 0)` + if (isBlockVisible) + blockPositionY = -35 + (50 * (30 - +blockPosition) / 30) + + if (isBitVisible) { + const bitPositionLocal = +bitPosition + const wellDepthLocal = +wellDepth + const altitude = 8 + //-75 + 75*bitPositionProc + const bitPositionProc = (bitPositionLocal)/(wellDepthLocal) + + if (bitPositionLocal < altitude) + bitPositionY = -75 + 16 * bitPositionLocal/altitude + else + bitPositionY = -59 + 59 * bitPositionLocal / wellDepthLocal + + if( wellDepthLocal > 20 && (wellDepthLocal - bitPositionLocal) > 2 && bitPositionProc > 0.96) + bitPositionY = -2 + } + + const blockTranslate = `translate(-75, ${blockPositionY})` + const bitTranslate = `translate(0, ${bitPositionY})` return ( @@ -125,26 +144,30 @@ export default function RigMnemo({ - - - - - - - - - - + {isBitVisible && + + + + + } + {isBlockVisible && + + + + + + } + {/* - + */} ); } diff --git a/src/pages/TelemetryView/UserOfWells.jsx b/src/pages/TelemetryView/UserOfWells.jsx index 144c8e9..ab002dd 100644 --- a/src/pages/TelemetryView/UserOfWells.jsx +++ b/src/pages/TelemetryView/UserOfWells.jsx @@ -1,6 +1,6 @@ import { Display } from '../../components/Display' -export const UserOfWells = ({ data }) => { +export const UserOfWell = ({ data }) => { const dataLast = data[data.length - 1] return + 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 [saubData, setSaubData] = useState([]) + const [dataSaub, setDataSaub] = useState([]) + const [dataSpin, setDataSpin] = useState([]) const [chartInterval, setChartInterval] = useState(defaultChartInterval) const [showLoader, setShowLoader] = useState(false) const options = timePeriodCollection.map((line) => ) - const handleReceiveDataSaub = (data) => { + const handleDataSaub = (data) => { if (data) { - setSaubData(data) + setDataSaub(data) + } + } + + const handleDataSpin = (data) => { + if (data) { + setDataSpin(data) } } useEffect(() => { invokeWebApiWrapperAsync( async () => { - const data = await DataService.getData(idWell, null, chartInterval) - handleReceiveDataSaub(data) + const dataSaub = await TelemetryDataSaubService.getData(idWell, null, chartInterval) + const dataSpin = await TelemetryDataSpinService.getData(idWell, null, chartInterval) + handleDataSaub(dataSaub) + handleDataSpin(dataSpin) }, setShowLoader, `Не удалось получить данные по скважине "${idWell}"`, ) - return Subscribe('hubs/telemetry', 'ReceiveDataSaub', `well_${idWell}`, handleReceiveDataSaub) + const unsubscribeSaub = Subscribe('hubs/telemetry', 'ReceiveDataSaub', `well_${idWell}`, handleDataSaub) + const unsubscribeSpin = Subscribe('hubs/telemetry', 'ReceiveDataSpin', `well_${idWell}`, handleDataSpin) + return () => { + unsubscribeSaub() + unsubscribeSpin() + } }, [idWell, chartInterval]) - const colSpan = 24 / (paramsGroups.length) - return ( - - - - -   - - Интервал:  - - -   - TorqueMaster - SpinMaster -

MSE

- - - -
- - - - - - - {paramsGroups.map((group, index) => - - - )} - - - - + + + + +
+ Интервал:  + +
+   + TorqueMaster + SpinMaster +

MSE

+ +
+
+ + + + {paramsGroups.map((group, index) => + + + )} + + + + +
) } \ No newline at end of file diff --git a/src/pages/TelemetryView/index_backup.jsx b/src/pages/TelemetryView/index_backup.jsx new file mode 100644 index 0000000..ae89ea9 --- /dev/null +++ b/src/pages/TelemetryView/index_backup.jsx @@ -0,0 +1,238 @@ +import {useState, useEffect} from 'react' +import {Row, Col, 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 {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: "Высота блока", + yDisplay: false, + linePv: {label: "blockPosition", units: 'м', xAccessorName: "blockPosition", yAccessorName: "date", color: '#333'}, + lineOther: { + label: "wellDepth", + units: 'м', + xAccessorName: "wellDepth", + yAccessorName: "date", + color: '#333', + showLine: false, + xConstValue: 30 + }, +} + +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] + +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 +} + +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) => ) + + const handleDataSaub = (data) => { + if (data) { + 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]) + + const colSpan = 24 / (paramsGroups.length) + + return ( + + + + +   + + Интервал:  + + +   + TorqueMaster + SpinMaster +

MSE

+ + + +
+ + + + + + + {paramsGroups.map((group, index) => + + + )} + + + + +
) +} \ No newline at end of file