Skip to content

Commit

Permalink
Refactor middleware hostname usage in CameraFeed components (#6875)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ashesh3 authored Dec 28, 2023
1 parent 3c008b2 commit cfe0011
Show file tree
Hide file tree
Showing 10 changed files with 46 additions and 89 deletions.
41 changes: 12 additions & 29 deletions src/Components/Assets/AssetType/HL7Monitor.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { SyntheticEvent, useEffect, useState } from "react";
import { AssetData } from "../AssetTypes";
import { AssetData, ResolvedMiddleware } from "../AssetTypes";
import * as Notification from "../../../Utils/Notifications.js";
import MonitorConfigure from "../configure/MonitorConfigure";
import Loading from "../../Common/Loading";
Expand All @@ -13,7 +13,6 @@ import VentilatorPatientVitalsMonitor from "../../VitalsMonitor/VentilatorPatien
import useAuthUser from "../../../Common/hooks/useAuthUser";
import request from "../../../Utils/request/request";
import routes from "../../../Redux/api";
import useQuery from "../../../Utils/request/useQuery";

interface HL7MonitorProps {
assetId: string;
Expand All @@ -22,27 +21,20 @@ interface HL7MonitorProps {
}

const HL7Monitor = (props: HL7MonitorProps) => {
const { assetId, asset, facilityId } = props;
const { assetId, asset } = props;
const [assetType, setAssetType] = useState("");
const [middlewareHostname, setMiddlewareHostname] = useState("");
const [facilityMiddlewareHostname, setFacilityMiddlewareHostname] =
useState("");
const [resolvedMiddleware, setResolvedMiddleware] =
useState<ResolvedMiddleware>();
const [isLoading, setIsLoading] = useState(true);
const [localipAddress, setLocalIPAddress] = useState("");
const [ipadrdress_error, setIpAddress_error] = useState("");
const authUser = useAuthUser();
const { data: facility, loading } = useQuery(routes.getPermittedFacility, {
pathParams: { id: facilityId },
onResponse: ({ res, data }) => {
if (res?.status === 200 && data && data.middleware_address) {
setFacilityMiddlewareHostname(data.middleware_address);
}
},
});

useEffect(() => {
setAssetType(asset?.asset_class);
setMiddlewareHostname(asset?.meta?.middleware_hostname);
setResolvedMiddleware(asset?.resolved_middleware);
setLocalIPAddress(asset?.meta?.local_ip_address);
setIsLoading(false);
}, [asset]);
Expand Down Expand Up @@ -76,10 +68,7 @@ const HL7Monitor = (props: HL7MonitorProps) => {
}
};

const fallbackMiddleware =
asset?.location_object?.middleware_address || facilityMiddlewareHostname;

if (isLoading || loading || !facility) return <Loading />;
if (isLoading) return <Loading />;
return (
<div className="mx-auto flex w-full xl:mt-8">
<div className="mx-auto flex flex-col gap-4 xl:flex-row-reverse">
Expand All @@ -94,23 +83,21 @@ const HL7Monitor = (props: HL7MonitorProps) => {
label={
<div className="flex flex-row gap-1">
<p>Middleware Hostname</p>
{!middlewareHostname && (
{resolvedMiddleware?.source != "asset" && (
<div className="tooltip">
<CareIcon
icon="l-info-circle"
className="tooltip text-indigo-500 hover:text-indigo-600"
/>
<span className="tooltip-text w-56 whitespace-normal">
Middleware hostname sourced from{" "}
{asset?.location_object?.middleware_address
? "asset location"
: "asset facility"}
Middleware hostname sourced from asset{" "}
{resolvedMiddleware?.source}
</span>
</div>
)}
</div>
}
placeholder={fallbackMiddleware}
placeholder={resolvedMiddleware?.hostname}
value={middlewareHostname}
onChange={(e) => setMiddlewareHostname(e.value)}
errorClassName="hidden"
Expand Down Expand Up @@ -140,16 +127,12 @@ const HL7Monitor = (props: HL7MonitorProps) => {

{assetType === "HL7MONITOR" && (
<HL7PatientVitalsMonitor
socketUrl={`wss://${
middlewareHostname || fallbackMiddleware
}/observations/${localipAddress}`}
socketUrl={`wss://${resolvedMiddleware?.hostname}/observations/${localipAddress}`}
/>
)}
{assetType === "VENTILATOR" && (
<VentilatorPatientVitalsMonitor
socketUrl={`wss://${
middlewareHostname || fallbackMiddleware
}/observations/${localipAddress}`}
socketUrl={`wss://${resolvedMiddleware?.hostname}/observations/${localipAddress}`}
/>
)}
</div>
Expand Down
33 changes: 11 additions & 22 deletions src/Components/Assets/AssetType/ONVIFCamera.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useEffect, useState } from "react";
import { AssetData } from "../AssetTypes";
import { AssetData, ResolvedMiddleware } from "../AssetTypes";
import * as Notification from "../../../Utils/Notifications.js";
import { BedModel } from "../../Facility/models";
import axios from "axios";
Expand Down Expand Up @@ -29,8 +29,8 @@ const ONVIFCamera = ({ assetId, facilityId, asset, onUpdated }: Props) => {
const [isLoading, setIsLoading] = useState(true);
const [assetType, setAssetType] = useState("");
const [middlewareHostname, setMiddlewareHostname] = useState("");
const [facilityMiddlewareHostname, setFacilityMiddlewareHostname] =
useState("");
const [resolvedMiddleware, setResolvedMiddleware] =
useState<ResolvedMiddleware>();
const [cameraAddress, setCameraAddress] = useState("");
const [ipadrdress_error, setIpAddress_error] = useState("");
const [username, setUsername] = useState("");
Expand All @@ -47,20 +47,11 @@ const ONVIFCamera = ({ assetId, facilityId, asset, onUpdated }: Props) => {
pathParams: { id: facilityId },
});
const authUser = useAuthUser();
useEffect(() => {
if (facility?.middleware_address) {
setFacilityMiddlewareHostname(facility.middleware_address);
}
}, [facility, facilityId]);

const fallbackMiddleware =
asset?.location_object?.middleware_address || facilityMiddlewareHostname;

const currentMiddleware = middlewareHostname || fallbackMiddleware;

useEffect(() => {
if (asset) {
setAssetType(asset?.asset_class);
setResolvedMiddleware(asset?.resolved_middleware);
const cameraConfig = getCameraConfig(asset);
setMiddlewareHostname(cameraConfig.middleware_hostname);
setCameraAddress(cameraConfig.hostname);
Expand All @@ -79,7 +70,7 @@ const ONVIFCamera = ({ assetId, facilityId, asset, onUpdated }: Props) => {
const data = {
meta: {
asset_type: "CAMERA",
middleware_hostname: middlewareHostname, // TODO: remove this infavour of facility.middleware_address
middleware_hostname: middlewareHostname,
local_ip_address: cameraAddress,
camera_access_key: `${username}:${password}:${streamUuid}`,
},
Expand Down Expand Up @@ -110,7 +101,7 @@ const ONVIFCamera = ({ assetId, facilityId, asset, onUpdated }: Props) => {
try {
setLoadingAddPreset(true);
const presetData = await axios.get(
`https://${currentMiddleware}/status?hostname=${config.hostname}&port=${config.port}&username=${config.username}&password=${config.password}`
`https://${resolvedMiddleware?.hostname}/status?hostname=${config.hostname}&port=${config.port}&username=${config.username}&password=${config.password}`
);

const { res } = await request(routes.createAssetBed, {
Expand Down Expand Up @@ -151,23 +142,21 @@ const ONVIFCamera = ({ assetId, facilityId, asset, onUpdated }: Props) => {
label={
<div className="flex flex-row gap-1">
<p>Middleware Hostname</p>
{!middlewareHostname && (
{resolvedMiddleware?.source != "asset" && (
<div className="tooltip">
<CareIcon
icon="l-info-circle"
className="tooltip text-indigo-500 hover:text-indigo-600"
/>
<span className="tooltip-text w-56 whitespace-normal">
Middleware hostname sourced from{" "}
{asset?.location_object?.middleware_address
? "asset location"
: "asset facility"}
Middleware hostname sourced from asset{" "}
{resolvedMiddleware?.source}
</span>
</div>
)}
</div>
}
placeholder={fallbackMiddleware}
placeholder={resolvedMiddleware?.hostname}
value={middlewareHostname}
onChange={({ value }) => setMiddlewareHostname(value)}
/>
Expand Down Expand Up @@ -225,7 +214,7 @@ const ONVIFCamera = ({ assetId, facilityId, asset, onUpdated }: Props) => {
addPreset={addPreset}
isLoading={loadingAddPreset}
refreshPresetsHash={refreshPresetsHash}
facilityMiddlewareHostname={currentMiddleware}
facilityMiddlewareHostname={resolvedMiddleware?.hostname || ""}
/>
) : null}
</div>
Expand Down
6 changes: 6 additions & 0 deletions src/Components/Assets/AssetTypes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ export interface AssetService {
note: string;
}

export interface ResolvedMiddleware {
hostname: string;
source: "asset" | "location" | "facility";
}

export interface AssetData {
id: string;
name: string;
Expand All @@ -93,6 +98,7 @@ export interface AssetData {
qr_code_id: string;
manufacturer: string;
warranty_amc_end_of_validity: string;
resolved_middleware?: ResolvedMiddleware;
last_service: AssetService;
meta?: {
[key: string]: any;
Expand Down
3 changes: 1 addition & 2 deletions src/Components/CameraFeed/CameraFeed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import Fullscreen from "../../CAREUI/misc/Fullscreen";
interface Props {
children?: React.ReactNode;
asset: AssetData;
fallbackMiddleware: string; // TODO: remove this in favour of `asset.resolved_middleware.hostname` once https://github.com/coronasafe/care/pull/1741 is merged
preset?: PTZPayload;
silent?: boolean;
className?: string;
Expand All @@ -29,7 +28,7 @@ interface Props {

export default function CameraFeed(props: Props) {
const playerRef = useRef<HTMLVideoElement | ReactPlayer | null>(null);
const streamUrl = getStreamUrl(props.asset, props.fallbackMiddleware);
const streamUrl = getStreamUrl(props.asset);

const player = usePlayer(streamUrl, playerRef);
const operate = useOperateCamera(props.asset.id, props.silent);
Expand Down
2 changes: 0 additions & 2 deletions src/Components/CameraFeed/CameraFeedWithBedPresets.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import AssetBedSelect from "./AssetBedSelect";

interface Props {
asset: AssetData;
fallbackMiddleware?: string;
}

export default function LocationFeedTile(props: Props) {
Expand All @@ -14,7 +13,6 @@ export default function LocationFeedTile(props: Props) {
return (
<CameraFeed
asset={props.asset}
fallbackMiddleware={props.fallbackMiddleware as string}
silent
preset={preset?.meta.position}
shortcutsDisabled
Expand Down
8 changes: 1 addition & 7 deletions src/Components/CameraFeed/CentralLiveMonitoring/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,7 @@ export default function CentralLiveMonitoring(props: { facilityId: string }) {
<div className="mt-1 grid grid-cols-1 place-content-center gap-1 lg:grid-cols-2 3xl:grid-cols-3">
{data.results.map((asset) => (
<div className="text-clip" key={asset.id}>
<LocationFeedTile
asset={asset}
fallbackMiddleware={
asset.location_object.middleware_address ||
facilityQuery.data?.middleware_address
}
/>
<LocationFeedTile asset={asset} />
</div>
))}
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/Components/CameraFeed/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ export const calculateVideoDelay = (
return playedDuration - video.currentTime;
};

export const getStreamUrl = (asset: AssetData, fallbackMiddleware?: string) => {
export const getStreamUrl = (asset: AssetData) => {
const config = getCameraConfig(asset);
const host = config.middleware_hostname || fallbackMiddleware;
const host = asset.resolved_middleware?.hostname;
const uuid = config.accessKey;

return isIOS
Expand Down
2 changes: 1 addition & 1 deletion src/Components/Common/FilePreviewDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ const FilePreviewDialog = (props: FilePreviewProps) => {
/>
) : (
<iframe
sandbox
sandbox=""
title="Source Files"
src={fileUrl}
className="mx-auto h-5/6 w-5/6 border-2 border-black bg-white md:my-6 md:w-4/6"
Expand Down
3 changes: 1 addition & 2 deletions src/Components/Facility/CentralNursingStation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,7 @@ export default function CentralNursingStation({ facilityId }: Props) {
setTotalCount(res.data.count);
setData(
entries.map(({ patient, asset, bed }) => {
const middleware =
asset.meta?.middleware_hostname || facilityObj?.middleware_address;
const middleware = asset.resolved_middleware?.hostname;
const local_ip_address = asset.meta?.local_ip_address;

return {
Expand Down
33 changes: 11 additions & 22 deletions src/Components/Facility/Consultations/Feed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { triggerGoal } from "../../../Integrations/Plausible.js";
import useAuthUser from "../../../Common/hooks/useAuthUser.js";
import Spinner from "../../Common/Spinner.js";
import useQuery from "../../../Utils/request/useQuery.js";
import { ResolvedMiddleware } from "../../Assets/AssetTypes.js";

interface IFeedProps {
facilityId: string;
Expand All @@ -35,7 +36,7 @@ interface IFeedProps {

const PATIENT_DEFAULT_PRESET = "Patient View".trim().toLowerCase();

export const Feed: React.FC<IFeedProps> = ({ consultationId, facilityId }) => {
export const Feed: React.FC<IFeedProps> = ({ consultationId }) => {
const dispatch: any = useDispatch();

const videoWrapper = useRef<HTMLDivElement>(null);
Expand All @@ -55,25 +56,10 @@ export const Feed: React.FC<IFeedProps> = ({ consultationId, facilityId }) => {
const [isFullscreen, setFullscreen] = useFullscreen();
const [videoStartTime, setVideoStartTime] = useState<Date | null>(null);
const [statusReported, setStatusReported] = useState(false);
const [facilityMiddlewareHostname, setFacilityMiddlewareHostname] =
useState("");
const [resolvedMiddleware, setResolvedMiddleware] =
useState<ResolvedMiddleware>();
const authUser = useAuthUser();

useQuery(routes.getPermittedFacility, {
pathParams: { id: facilityId || "" },
onResponse: ({ res, data }) => {
if (res && res.status === 200 && data && data.middleware_address) {
setFacilityMiddlewareHostname(data.middleware_address);
}
},
});

const fallbackMiddleware =
cameraAsset.location_middleware || facilityMiddlewareHostname;

const currentMiddleware =
cameraAsset.middleware_address || fallbackMiddleware;

useEffect(() => {
if (cameraState) {
setCameraState({
Expand Down Expand Up @@ -136,6 +122,9 @@ export const Feed: React.FC<IFeedProps> = ({ consultationId, facilityId }) => {
bedAssets.data.results[0].asset_object.location_object
?.middleware_address,
});
setResolvedMiddleware(
bedAssets.data.results[0].asset_object.resolved_middleware
);
setCameraConfig(bedAssets.data.results[0].meta);
setCameraState({
...bedAssets.data.results[0].meta.position,
Expand Down Expand Up @@ -173,8 +162,8 @@ export const Feed: React.FC<IFeedProps> = ({ consultationId, facilityId }) => {
);

const url = !isIOS
? `wss://${currentMiddleware}/stream/${cameraAsset?.accessKey}/channel/0/mse?uuid=${cameraAsset?.accessKey}&channel=0`
: `https://${currentMiddleware}/stream/${cameraAsset?.accessKey}/channel/0/hls/live/index.m3u8?uuid=${cameraAsset?.accessKey}&channel=0`;
? `wss://${resolvedMiddleware?.hostname}/stream/${cameraAsset?.accessKey}/channel/0/mse?uuid=${cameraAsset?.accessKey}&channel=0`
: `https://${resolvedMiddleware?.hostname}/stream/${cameraAsset?.accessKey}/channel/0/hls/live/index.m3u8?uuid=${cameraAsset?.accessKey}&channel=0`;

const {
startStream,
Expand All @@ -185,7 +174,7 @@ export const Feed: React.FC<IFeedProps> = ({ consultationId, facilityId }) => {
: // eslint-disable-next-line react-hooks/rules-of-hooks
useMSEMediaPlayer({
config: {
middlewareHostname: currentMiddleware,
middlewareHostname: resolvedMiddleware?.hostname ?? "",
...cameraAsset,
},
url,
Expand Down Expand Up @@ -254,7 +243,7 @@ export const Feed: React.FC<IFeedProps> = ({ consultationId, facilityId }) => {
});
getBedPresets(cameraAsset);
}
}, [cameraAsset, currentMiddleware]);
}, [cameraAsset, resolvedMiddleware?.hostname]);

useEffect(() => {
let tId: any;
Expand Down

0 comments on commit cfe0011

Please sign in to comment.