From 71fc1b47d39affde6e87759f1d822a131a0f5fce Mon Sep 17 00:00:00 2001 From: Jack Harper Date: Fri, 30 Aug 2024 16:09:14 +0100 Subject: [PATCH 1/2] try and typescriptify instrumentdata - now not working --- .../{InstrumentData.js => InstrumentData.tsx} | 69 +++++++++++++------ app/components/dehex_and_decompress.ts | 2 +- 2 files changed, 50 insertions(+), 21 deletions(-) rename app/components/{InstrumentData.js => InstrumentData.tsx} (83%) diff --git a/app/components/InstrumentData.js b/app/components/InstrumentData.tsx similarity index 83% rename from app/components/InstrumentData.js rename to app/components/InstrumentData.tsx index 7f4dc3f..7049a7e 100644 --- a/app/components/InstrumentData.js +++ b/app/components/InstrumentData.tsx @@ -8,22 +8,43 @@ import { dehex_and_decompress } from "./dehex_and_decompress"; import { Instrument } from "./Instrument"; import {PV} from "./PV"; -let lastUpdate = ""; +let lastUpdate: string = ""; + +interface PVWSMessage { + type: string; + pv: string; + value?: number|null; + text?: string|null; + b64byt?: string|null; + units?: string|null; + precision?: number|null; + labels?: string|null; + min?: number|null; + max?: number|null; + warn_low?: number|null; + warn_high?: number|null; + alarm_low?: number|null; + alarm_high?: number|null; + severity?: string|null; + seconds?: number|null; + readonly?: boolean|null; + nanos?: number|null; +} -export default function InstrumentData({instrumentName}) { +export default function InstrumentData({instrumentName}: {instrumentName:string} ) { // set up the different states for the instrument data - const socketURL = process.env.NEXT_PUBLIC_WS_URL; + const socketURL = process.env.NEXT_PUBLIC_WS_URL || "ws://localhost:8080/pvws/pv"; const instName = instrumentName ; - const { sendJsonMessage, lastJsonMessage } = useWebSocket(socketURL, { + const { sendJsonMessage, lastJsonMessage }: {sendJsonMessage:any,lastJsonMessage:PVWSMessage} = useWebSocket(socketURL, { shouldReconnect: (closeEvent) => true, }); const CONFIG_DETAILS = "CS:BLOCKSERVER:GET_CURR_CONFIG_DETAILS"; - const [instlist, setInstlist] = useState(null); - const [currentInstrument, setCurrentInstrument] = useState(null); + const [instlist, setInstlist] = useState|null>(null); + const [currentInstrument, setCurrentInstrument] = useState(null); useEffect(() => { sendJsonMessage({ @@ -78,11 +99,15 @@ export default function InstrumentData({instrumentName}) { if (!lastJsonMessage) { return; } - const updatedPV = lastJsonMessage; - const updatedPVName = updatedPV.pv; - - if (updatedPVName == "CS:INSTLIST" && updatedPV.b64byt != null) { - setInstlist(JSON.parse(dehex_and_decompress(atob(updatedPV.b64byt)))); + const updatedPV: PVWSMessage = lastJsonMessage; + const updatedPVName: string = updatedPV.pv; + const updatedPVbytes: string|null|undefined = updatedPV.b64byt; + + if (updatedPVName == "CS:INSTLIST" && updatedPVbytes != null) { + const dehexedInstList = dehex_and_decompress(atob(updatedPVbytes)) + if (dehexedInstList != null && typeof dehexedInstList == "string") { + setInstlist(JSON.parse(dehexedInstList)); + } } if (!currentInstrument) { @@ -91,19 +116,23 @@ export default function InstrumentData({instrumentName}) { if ( updatedPVName == `${currentInstrument.prefix}${CONFIG_DETAILS}` && - updatedPV.b64byt != null + updatedPVbytes != null ) { // config change, reset instrument groups - if (updatedPV.b64byt == lastUpdate) { + if (updatedPVbytes == lastUpdate) { //config hasnt actually changed return; } - lastUpdate = updatedPV.b64byt; + lastUpdate = updatedPVbytes; console.log("config changed"); - let raw = updatedPV.b64byt; + let raw = updatedPVbytes; const res = dehex_and_decompress(atob(raw)); + + if (res == null || typeof res != "string") { + return; + } const response = JSON.parse(res); //parse it here @@ -126,7 +155,7 @@ export default function InstrumentData({instrumentName}) { }); for (const block of groupBlocks) { - const newBlock = blocks.find((b) => b.name === block); + const newBlock = blocks.find((b:any) => b.name === block); const completePV = new PV(newBlock.pv); completePV.human_readable_name = newBlock.name; @@ -158,9 +187,9 @@ export default function InstrumentData({instrumentName}) { if (updatedPV.text != null) { //string pvVal = updatedPV.text; - } else if (updatedPV.b64byt != null) { + } else if (updatedPVbytes != null) { //pv is base64 encoded - pvVal = atob(updatedPV.b64byt); + pvVal = atob(updatedPVbytes); } else if (updatedPV.value != null) { //anything else pvVal = updatedPV.value; @@ -189,11 +218,11 @@ export default function InstrumentData({instrumentName}) { pvs: [value_pv], }); } - } else if (currentInstrument.columnZeroPVs.has(updatedPVName)) { + } else if (currentInstrument.columnZeroPVs.has(updatedPVName) && updatedPVbytes != null ) { // this is a top bar column zero value const row = updatedPVName.endsWith("TITLE") ? 0 : 1; // if title, column 1 // Both of these are base64 encoded. PVWS gives a null byte back if there is no value, so replace with null. - const value = atob(updatedPV.b64byt) != "\x00" ? atob(updatedPV.b64byt) : null; + const value = atob(updatedPVbytes) != "\x00" ? atob(updatedPVbytes) : null; currentInstrument.topBarPVs.set(updatedPVName, [ row, 0, diff --git a/app/components/dehex_and_decompress.ts b/app/components/dehex_and_decompress.ts index 74d6970..4cec728 100644 --- a/app/components/dehex_and_decompress.ts +++ b/app/components/dehex_and_decompress.ts @@ -16,7 +16,7 @@ function unhexlify(str: string): string { */ export function dehex_and_decompress( input: string, -): string | Uint8Array | undefined { +): string | Uint8Array | null { // DEHEX const unhexed = unhexlify(input); const charData = unhexed.split("").map(function (x) { From ec6d9c3d6c00bbf80fbc5d6ef682a7680f43c74f Mon Sep 17 00:00:00 2001 From: Jack Harper Date: Thu, 12 Sep 2024 09:00:30 +0100 Subject: [PATCH 2/2] move pvws message interface out into new file --- app/components/IfcPVWSMessage.tsx | 20 ++++++++++++++++++++ app/components/InstrumentData.tsx | 22 +--------------------- 2 files changed, 21 insertions(+), 21 deletions(-) create mode 100644 app/components/IfcPVWSMessage.tsx diff --git a/app/components/IfcPVWSMessage.tsx b/app/components/IfcPVWSMessage.tsx new file mode 100644 index 0000000..5f2e049 --- /dev/null +++ b/app/components/IfcPVWSMessage.tsx @@ -0,0 +1,20 @@ +export interface PVWSMessage { + type: string; + pv: string; + value?: number | null; + text?: string | null; + b64byt?: string | null; + units?: string | null; + precision?: number | null; + labels?: string | null; + min?: number | null; + max?: number | null; + warn_low?: number | null; + warn_high?: number | null; + alarm_low?: number | null; + alarm_high?: number | null; + severity?: string | null; + seconds?: number | null; + readonly?: boolean | null; + nanos?: number | null; +} diff --git a/app/components/InstrumentData.tsx b/app/components/InstrumentData.tsx index 7049a7e..d19aff9 100644 --- a/app/components/InstrumentData.tsx +++ b/app/components/InstrumentData.tsx @@ -7,30 +7,10 @@ import useWebSocket from "react-use-websocket"; import { dehex_and_decompress } from "./dehex_and_decompress"; import { Instrument } from "./Instrument"; import {PV} from "./PV"; +import { PVWSMessage } from "./IfcPVWSMessage"; let lastUpdate: string = ""; -interface PVWSMessage { - type: string; - pv: string; - value?: number|null; - text?: string|null; - b64byt?: string|null; - units?: string|null; - precision?: number|null; - labels?: string|null; - min?: number|null; - max?: number|null; - warn_low?: number|null; - warn_high?: number|null; - alarm_low?: number|null; - alarm_high?: number|null; - severity?: string|null; - seconds?: number|null; - readonly?: boolean|null; - nanos?: number|null; -} - export default function InstrumentData({instrumentName}: {instrumentName:string} ) { // set up the different states for the instrument data