Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
287ec8a
Get worker status in the beamline stats tab
noemifrisina Jun 13, 2025
03ce9fe
Remove sleep button
noemifrisina Jun 13, 2025
073033d
Tidy up
noemifrisina Jun 13, 2025
f8e0169
Make PV boxes a bit more visible
noemifrisina Jun 13, 2025
ccfdec9
Some friday afternoon attempts at a more general pv box
noemifrisina Jun 13, 2025
a78cd6f
Some friday afternoon attempts at a more general pv box - and save
noemifrisina Jun 13, 2025
fd5fcb1
Figuring out how the various parts of PVComponent work and trying to …
noemifrisina Jun 17, 2025
becb455
The beginning of tidying up
noemifrisina Jun 18, 2025
bac4f0f
Tidy up the various Pv component parts
noemifrisina Jun 18, 2025
9469829
Remove now empty file
noemifrisina Jun 18, 2025
13d67dd
Fix all imports
noemifrisina Jun 18, 2025
b15818a
Render doesn't work as expected
noemifrisina Jun 18, 2025
fc90855
Try this
noemifrisina Jun 18, 2025
f5c51de
Temp fix for flux
noemifrisina Jun 19, 2025
98513ba
Tidy up a bit more
noemifrisina Jun 19, 2025
c2fbb73
Add link with issue
noemifrisina Jun 19, 2025
a212f88
Fix import
noemifrisina Jun 19, 2025
bdcc1e4
Add transmission
noemifrisina Jun 19, 2025
c02bb47
Add Pmac stages to stats
noemifrisina Jun 19, 2025
4161215
Some thoughts
noemifrisina Jun 24, 2025
d3f1cf5
Update some packages
noemifrisina Jul 2, 2025
c3aefc1
Slightly better but not yet
noemifrisina Jul 2, 2025
c1ce065
Ok, almost, now need to fix the original bits
noemifrisina Jul 2, 2025
70a0091
A bit better
noemifrisina Jul 2, 2025
0ca6892
Merge branch 'main' into 8-23_tidy-up-buttons-and-fields
noemifrisina Jul 8, 2025
83beaf7
Add a detector state box in the detector tab
noemifrisina Jul 8, 2025
eb008ae
Merge branch 'main' into 8-23_tidy-up-buttons-and-fields
noemifrisina Jul 8, 2025
23e0ae1
Use a box for Detector tab
noemifrisina Jul 8, 2025
8ac8306
Merge branch 'main' into 8-23_tidy-up-buttons-and-fields
noemifrisina Jul 22, 2025
b895ded
Merge branch 'main' into 8-23_tidy-up-buttons-and-fields
noemifrisina Jul 23, 2025
c14d370
Make button contained
noemifrisina Jul 25, 2025
4a37f06
Use cards
noemifrisina Jul 25, 2025
7be484e
Separate card
noemifrisina Jul 25, 2025
14fcdeb
Make a custom card for beamline stats
noemifrisina Jul 28, 2025
81947c0
Some renaming
noemifrisina Jul 28, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,468 changes: 615 additions & 853 deletions package-lock.json

Large diffs are not rendered by default.

11 changes: 3 additions & 8 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { DetectorMotionTabPanel } from "./screens/DetectorMotion";
import { BeamlineStatsTabPanel } from "./screens/BeamlineStats";
import { OavMover } from "./screens/OavMover";
import "./App.css";
import { BlueApiInfo } from "./screens/BlueApiInfo";
import { ParamsPanel } from "./screens/CollectionPanel";
import {
ColourSchemeButton,
Expand Down Expand Up @@ -64,15 +63,14 @@ function FixedTargetPanels() {
textColor="secondary"
centered
>
<Tab label="BlueAPI info" {...a11yProps(0)} />
<Tab label="Beamline info" {...a11yProps(0)} />
<Tab label="Detector position" {...a11yProps(1)} />
<Tab label="OAV view" {...a11yProps(2)} />
<Tab label="Beamline stats" {...a11yProps(3)} />
<Tab label="Fixed Target Collection" {...a11yProps(4)} />
<Tab label="Fixed Target Collection" {...a11yProps(3)} />
</Tabs>
</Box>
<CustomTabPanel value={value} index={0}>
<BlueApiInfo />
<BeamlineStatsTabPanel />
</CustomTabPanel>
<CustomTabPanel value={value} index={1}>
<DetectorMotionTabPanel />
Expand All @@ -81,9 +79,6 @@ function FixedTargetPanels() {
<OavMover />
</CustomTabPanel>
<CustomTabPanel value={value} index={3}>
<BeamlineStatsTabPanel />
</CustomTabPanel>
<CustomTabPanel value={value} index={4}>
<ParamsPanel />
</CustomTabPanel>
</div>
Expand Down
6 changes: 5 additions & 1 deletion src/CustomTheme.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ declare module "@mui/material/styles" {
}
}

// Update the Button's color options to include a violet option
// Update the Button's color options to include a new option
declare module "@mui/material/Button" {
interface ButtonPropsColorOverrides {
custom: true;
Expand Down Expand Up @@ -49,6 +49,10 @@ export const I24DiamondTheme: Theme = createTheme({
dark: "#10569b",
contrastText: "#ffffff", // white
},
background: {
default: "#050505",
paper: "#121212",
},
},
},
},
Expand Down
10 changes: 5 additions & 5 deletions src/components/OavVideoStream.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Box } from "@mui/material";
import { PvComponent } from "../pv/PvComponent";
import { PvItem, PvDescription } from "../pv/types";
import {
PvComponent,
PvItem,
PvDescription,
parseNumericPv,
pvIntArrayToString,
useParsedPvConnection,
} from "../pv/PvComponent";
import { parseNumericPv, pvIntArrayToString } from "../pv/util";
} from "../pv/util";
import React from "react";

export const useContainerDimensions = (
Expand Down
4 changes: 2 additions & 2 deletions src/components/SelectionControl.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React from "react";
import { PvDescription, useParsedPvConnection } from "../pv/PvComponent";
import { PvDescription } from "../pv/types";
import { submitAndRunPlanImmediately } from "../blueapi/blueapi";
import { FormControl, InputLabel, MenuItem, Select } from "@mui/material";
import { forceString } from "../pv/util";
import { forceString, useParsedPvConnection } from "../pv/util";

type SelectionProps = PvDescription & {
id: string;
Expand Down
32 changes: 0 additions & 32 deletions src/components/SleepButton.tsx

This file was deleted.

26 changes: 14 additions & 12 deletions src/components/WorkerStatus.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Box, Stack } from "@mui/material";
import { Box, Grid2, Stack } from "@mui/material";

import { processUseBlueApiCall, useBlueApiCall } from "../blueapi/blueapi";
import { useState } from "react";
Expand All @@ -7,16 +7,18 @@ export function WorkerStatus() {
const [currentState, setCurrentState] = useState<string>("UNKNOWN");
const workerStateInfo = useBlueApiCall("/worker/state");
return (
<Stack padding={1} direction={"row"} spacing={1}>
<b>BlueAPI worker status: </b>
<Box>
{processUseBlueApiCall(workerStateInfo, (res) => {
if (!res.bodyUsed) {
res.json().then((text) => setCurrentState(text));
}
return currentState;
})}
</Box>
</Stack>
<Grid2 size={12}>
<Stack direction={"row"} spacing={1} justifyContent={"center"}>
<b>BlueAPI worker status: </b>
<Box>
{processUseBlueApiCall(workerStateInfo, (res) => {
if (!res.bodyUsed) {
res.json().then((text) => setCurrentState(text));
}
return currentState;
})}
</Box>
</Stack>
</Grid2>
);
}
75 changes: 41 additions & 34 deletions src/pv/PvComponent.tsx
Original file line number Diff line number Diff line change
@@ -1,48 +1,55 @@
import { useConnection } from "@diamondlightsource/cs-web-lib";
import { Box } from "@mui/material";
import { Box, useTheme } from "@mui/material";
import { ErrorBoundary } from "react-error-boundary";
import { RawValue } from "./util";
import { PvComponentProps, PvDescription, PvItem } from "./types";
import { useParsedPvConnection, forceString } from "./util";

type Transformer = (value: RawValue) => string | number;
export type PvDisplayTypes = string | number;
export type PvItem = { label: string; value: RawValue | PvDisplayTypes };
export type PvItemComponent = ({ label, value }: PvItem) => JSX.Element;
export type PvItemHandler = ({ label, value }: PvItem) => void;
export type PvDescription = {
label: string;
pv: string;
};
export type PvComponentProps = PvDescription & {
render: PvItemComponent;
transformValue?: Transformer;
};

export function useParsedPvConnection(
props: PvDescription & { transformValue?: Transformer }
) {
const [_effectivePvName, connected, _readonly, latestValue] = useConnection(
props.label,
props.pv
);
const rawValue: RawValue = connected ? latestValue : "not connected";
const returnValue = props.transformValue
? props.transformValue(rawValue)
: rawValue;
console.log(
`fetched parsed value ${returnValue} for PV: ${props.pv} labeled ${props.label}`
function defaultPvBox(label: string, value: number | string): JSX.Element {
return (
<Box>
<p>
<b>{label}:</b> {value}
</p>
</Box>
);
return returnValue;
}

function WsPvComponent(props: PvComponentProps) {
function WsPvComponent(props: PvComponentProps): JSX.Element {
const latestValue = useParsedPvConnection(props);
return <Box>{props.render({ label: props.label, value: latestValue })}</Box>;
const renderedPvBox = props.render ? (
<Box>{props.render({ label: props.label, value: latestValue })}</Box>
) : (
defaultPvBox(props.label, latestValue)
);
return renderedPvBox;
}

export function PvComponent(props: PvComponentProps) {
const theme = useTheme();
return (
<ErrorBoundary fallback={<p>Error Connecting!</p>}>
<ErrorBoundary
fallback={
<Box color={theme.palette.error.main}>
<p>Error Connecting!</p>
</Box>
}
>
{WsPvComponent(props)}
</ErrorBoundary>
);
}

export function RoPvBox(props: PvDescription) {
return PvComponent({
...props,
transformValue: forceString,
render: (props: PvItem) => {
return (
<Box>
<p>
{props.label} : {props.value}
</p>
</Box>
);
},
});
}
30 changes: 30 additions & 0 deletions src/pv/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { DType } from "@diamondlightsource/cs-web-lib";

type NotConnected = "not connected";
export type RawValue = DType | undefined | NotConnected;

type TransformString = (value: RawValue) => string | number;
type TransformNumeric = (
value: RawValue,
decimals?: number,
scaleFactor?: number
) => string | number;
export type PvTransformer = TransformString | TransformNumeric;

export type PvDescription = {
label: string;
pv: string;
};

export type PvItem = { label: string; value: number | string | NotConnected };
type PvItemComponent = ({ label, value }: PvItem) => JSX.Element;

export type RenderedPvValue = RawValue | string | number;

export type ParsePvProps = PvDescription & {
transformValue: PvTransformer;
decimals?: number;
scaleFactor?: number;
};

export type PvComponentProps = ParsePvProps & { render?: PvItemComponent };
39 changes: 37 additions & 2 deletions src/pv/util.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { DType } from "@diamondlightsource/cs-web-lib";
export type RawValue = DType | "not connected" | undefined;
import { useConnection } from "@diamondlightsource/cs-web-lib";
import { ParsePvProps, PvDescription, RawValue } from "./types";

export function forceString(value: RawValue | string | number): string {
let displayValue: string;
Expand All @@ -21,7 +22,7 @@ export function parseNumericPv(
value: string | number | DType | undefined,
decimals?: number,
scaleFactor?: number
) {
): string {
const decimalsToUse = decimals ? decimals : 2;
const scaleFactorToUse = scaleFactor ? scaleFactor : 1;
if (value === undefined) {
Expand Down Expand Up @@ -57,3 +58,37 @@ export function pvIntArrayToString(value: RawValue): string {
}
}
}

function ReadPvRawValue(props: PvDescription): RawValue {
const [_effectivePvName, connected, _readonly, latestValue] = useConnection(
props.label,
props.pv
);
const rawValue: RawValue = connected ? latestValue : "not connected";
return rawValue;
}

export function useParsedPvConnection(props: ParsePvProps): number | string {
const rawValue = ReadPvRawValue({ label: props.label, pv: props.pv });
let returnValue;
if (rawValue === "not connected") {
returnValue = "not connected";
} else if (!rawValue) {
console.error("Parsed value was undefined");
returnValue = "undefined";
} else {
returnValue = props.transformValue
? props.transformValue(rawValue, props.decimals, props.scaleFactor)
: rawValue;
}

// If it's a Dtype cast to string
if (typeof returnValue !== "string" || typeof returnValue !== "number") {
returnValue = returnValue.toString();
}

console.log(
`fetched parsed value ${returnValue} for PV: ${props.pv} labeled ${props.label}`
);
return returnValue;
}
Loading