diff --git a/.gitignore b/.gitignore index 6d8d639..58e26c1 100644 --- a/.gitignore +++ b/.gitignore @@ -29,7 +29,7 @@ DebuggerCmd.md *.ntvs* *.njsproj *.sw? - +prompt.md *.tsbuildinfo # Generated Files diff --git a/TODO.md b/TODO.md deleted file mode 100644 index 50554da..0000000 --- a/TODO.md +++ /dev/null @@ -1,13 +0,0 @@ -# TODO - -1. 后端HTTP视频流 - -640*480, RGB565 -0x0000_0000 + 25800 - - -2. 信号发生器界面导入.dat文件 -3. 示波器后端交互、前端界面 -4. 逻辑分析仪后端交互、前端界面 -5. 前端重构 -6. 数据库 —— 用户登录、板卡资源分配、板卡IP地址分配 \ No newline at end of file diff --git a/src/components/LabCanvas/composable/diagramManager.ts b/src/components/LabCanvas/composable/diagramManager.ts index a03403b..a1e88d7 100644 --- a/src/components/LabCanvas/composable/diagramManager.ts +++ b/src/components/LabCanvas/composable/diagramManager.ts @@ -1,3 +1,6 @@ +import { ResourcePurpose } from "@/APIClient"; +import { AuthManager } from "@/utils/AuthManager"; + // 定义 diagram.json 的类型结构 export interface DiagramData { version: number; @@ -26,40 +29,43 @@ export interface DiagramPart { // 连接类型定义 - 使用元组类型表示四元素数组 export type ConnectionArray = [string, string, number, string[]]; -import { AuthManager } from '@/utils/AuthManager'; - // 解析连接字符串为组件ID和引脚ID -export function parseConnectionPin(connectionPin: string): { componentId: string; pinId: string } { - const [componentId, pinId] = connectionPin.split(':'); +export function parseConnectionPin(connectionPin: string): { + componentId: string; + pinId: string; +} { + const [componentId, pinId] = connectionPin.split(":"); return { componentId, pinId }; } // 将连接数组转换为适用于渲染的格式 export function connectionArrayToWireItem( - connection: ConnectionArray, - index: number, - startPos = { x: 0, y: 0 }, - endPos = { x: 0, y: 0 } + connection: ConnectionArray, + index: number, + startPos = { x: 0, y: 0 }, + endPos = { x: 0, y: 0 }, ): WireItem { const [startPinStr, endPinStr, width, path] = connection; - const { componentId: startComponentId, pinId: startPinId } = parseConnectionPin(startPinStr); - const { componentId: endComponentId, pinId: endPinId } = parseConnectionPin(endPinStr); - + const { componentId: startComponentId, pinId: startPinId } = + parseConnectionPin(startPinStr); + const { componentId: endComponentId, pinId: endPinId } = + parseConnectionPin(endPinStr); + return { id: `wire-${index}`, startX: startPos.x, startY: startPos.y, - endX: endPos.x, + endX: endPos.x, endY: endPos.y, startComponentId, startPinId, endComponentId, endPinId, strokeWidth: width, - color: '#4a5568', // 默认颜色 - routingMode: 'path', + color: "#4a5568", // 默认颜色 + routingMode: "path", pathCommands: path, - showLabel: false + showLabel: false, }; } @@ -76,7 +82,7 @@ export interface WireItem { endPinId?: string; strokeWidth: number; color: string; - routingMode: 'orthogonal' | 'path'; + routingMode: "orthogonal" | "path"; constraint?: string; pathCommands?: string[]; showLabel: boolean; @@ -89,57 +95,63 @@ export async function loadDiagramData(examId?: string): Promise { if (examId) { try { const resourceClient = AuthManager.createAuthenticatedResourceClient(); - + // 获取diagram类型的资源列表 - const resources = await resourceClient.getResourceList(examId, 'canvas', 'template'); - + const resources = await resourceClient.getResourceList( + examId, + "canvas", + ResourcePurpose.Template, + ); + if (resources && resources.length > 0) { // 获取第一个diagram资源 const diagramResource = resources[0]; - + // 使用动态API获取资源文件内容 - const response = await resourceClient.getResourceById(diagramResource.id); - + const response = await resourceClient.getResourceById( + diagramResource.id, + ); + if (response && response.data) { const text = await response.data.text(); const data = JSON.parse(text); - + // 验证数据格式 const validation = validateDiagramData(data); if (validation.isValid) { - console.log('成功从API加载实验diagram:', examId); + console.log("成功从API加载实验diagram:", examId); return data; } else { - console.warn('API返回的diagram数据格式无效:', validation.errors); + console.warn("API返回的diagram数据格式无效:", validation.errors); } } } else { - console.log('未找到实验diagram资源,使用默认加载方式'); + console.log("未找到实验diagram资源,使用默认加载方式"); } } catch (error) { - console.warn('从API加载实验diagram失败,使用默认加载方式:', error); + console.warn("从API加载实验diagram失败,使用默认加载方式:", error); } } - + // 如果没有examId或API加载失败,尝试从静态文件加载(不再使用本地存储) - + // 从静态文件加载(作为备选方案) - const response = await fetch('/src/components/diagram.json'); + const response = await fetch("/src/components/diagram.json"); if (!response.ok) { throw new Error(`Failed to load diagram.json: ${response.statusText}`); } const data = await response.json(); - + // 验证静态文件数据 const validation = validateDiagramData(data); if (validation.isValid) { return data; } else { - console.warn('静态diagram文件数据格式无效:', validation.errors); - throw new Error('所有diagram数据源都无效'); + console.warn("静态diagram文件数据格式无效:", validation.errors); + throw new Error("所有diagram数据源都无效"); } } catch (error) { - console.error('Error loading diagram data:', error); + console.error("Error loading diagram data:", error); // 返回空的默认数据结构 return createEmptyDiagram(); } @@ -149,33 +161,31 @@ export async function loadDiagramData(examId?: string): Promise { export function createEmptyDiagram(): DiagramData { return { version: 1, - author: 'user', - editor: 'user', + author: "user", + editor: "user", parts: [], - connections: [] + connections: [], }; } // 保存图表数据(已禁用本地存储) export function saveDiagramData(data: DiagramData): void { // 本地存储功能已禁用 - 不再保存到localStorage - console.debug('saveDiagramData called but localStorage saving is disabled'); + console.debug("saveDiagramData called but localStorage saving is disabled"); } // 更新组件位置 export function updatePartPosition( - data: DiagramData, - partId: string, - x: number, - y: number + data: DiagramData, + partId: string, + x: number, + y: number, ): DiagramData { return { ...data, - parts: data.parts.map(part => - part.id === partId - ? { ...part, x, y } - : part - ) + parts: data.parts.map((part) => + part.id === partId ? { ...part, x, y } : part, + ), }; } @@ -184,21 +194,21 @@ export function updatePartAttribute( data: DiagramData, partId: string, attrName: string, - value: any + value: any, ): DiagramData { return { ...data, - parts: data.parts.map(part => - part.id === partId - ? { - ...part, - attrs: { - ...part.attrs, - [attrName]: value - } - } - : part - ) + parts: data.parts.map((part) => + part.id === partId + ? { + ...part, + attrs: { + ...part.attrs, + [attrName]: value, + }, + } + : part, + ), }; } @@ -210,72 +220,79 @@ export function addConnection( endComponentId: string, endPinId: string, width: number = 2, - path: string[] = [] + path: string[] = [], ): DiagramData { const newConnection: ConnectionArray = [ `${startComponentId}:${startPinId}`, `${endComponentId}:${endPinId}`, width, - path + path, ]; - + return { ...data, - connections: [...data.connections, newConnection] + connections: [...data.connections, newConnection], }; } // 删除连接 export function deleteConnection( data: DiagramData, - connectionIndex: number + connectionIndex: number, ): DiagramData { return { ...data, - connections: data.connections.filter((_, index) => index !== connectionIndex) + connections: data.connections.filter( + (_, index) => index !== connectionIndex, + ), }; } // 查找与组件关联的所有连接 export function findConnectionsByPart( data: DiagramData, - partId: string + partId: string, ): { connection: ConnectionArray; index: number }[] { return data.connections .map((connection, index) => ({ connection, index })) .filter(({ connection }) => { const [startPin, endPin] = connection; - const startCompId = startPin.split(':')[0]; - const endCompId = endPin.split(':')[0]; + const startCompId = startPin.split(":")[0]; + const endCompId = endPin.split(":")[0]; return startCompId === partId || endCompId === partId; }); } // 添加验证diagram.json文件的函数 -export function validateDiagramData(data: any): { isValid: boolean; errors: string[] } { +export function validateDiagramData(data: any): { + isValid: boolean; + errors: string[]; +} { const errors: string[] = []; - + // 检查版本号 if (!data.version) { - errors.push('缺少version字段'); + errors.push("缺少version字段"); } - + // 检查parts数组 if (!Array.isArray(data.parts)) { - errors.push('parts字段不是数组'); + errors.push("parts字段不是数组"); } else { // 验证parts中的每个对象 data.parts.forEach((part: any, index: number) => { if (!part.id) errors.push(`parts[${index}]缺少id`); if (!part.type) errors.push(`parts[${index}]缺少type`); - if (typeof part.x !== 'number') errors.push(`parts[${index}]缺少有效的x坐标`); - if (typeof part.y !== 'number') errors.push(`parts[${index}]缺少有效的y坐标`); + if (typeof part.x !== "number") + errors.push(`parts[${index}]缺少有效的x坐标`); + if (typeof part.y !== "number") + errors.push(`parts[${index}]缺少有效的y坐标`); }); } - + // 检查connections数组 if (!Array.isArray(data.connections)) { - errors.push('connections字段不是数组'); + errors.push("connections字段不是数组"); } else { // 验证connections中的每个数组 data.connections.forEach((conn: any, index: number) => { @@ -283,25 +300,25 @@ export function validateDiagramData(data: any): { isValid: boolean; errors: stri errors.push(`connections[${index}]不是有效的连接数组`); return; } - + const [startPin, endPin, width] = conn; - - if (typeof startPin !== 'string' || !startPin.includes(':')) { + + if (typeof startPin !== "string" || !startPin.includes(":")) { errors.push(`connections[${index}]的起始针脚格式无效`); } - - if (typeof endPin !== 'string' || !endPin.includes(':')) { + + if (typeof endPin !== "string" || !endPin.includes(":")) { errors.push(`connections[${index}]的结束针脚格式无效`); } - - if (typeof width !== 'number') { + + if (typeof width !== "number") { errors.push(`connections[${index}]的宽度不是有效的数字`); } }); } - + return { isValid: errors.length === 0, - errors + errors, }; } diff --git a/src/components/LabCanvas/index.ts b/src/components/LabCanvas/index.ts index 8ccb84f..c5b180e 100644 --- a/src/components/LabCanvas/index.ts +++ b/src/components/LabCanvas/index.ts @@ -31,7 +31,7 @@ export const previewSizes: Record = { Switch: 0.35, Pin: 0.8, SMT_LED: 0.7, - SevenSegmentDisplay: 0.4, + SevenSegmentDisplayUltimate: 0.4, HDMI: 0.5, DDR: 0.5, ETH: 0.5, @@ -50,7 +50,7 @@ export const availableComponents: ComponentConfig[] = [ { type: "Switch", name: "开关" }, { type: "Pin", name: "引脚" }, { type: "SMT_LED", name: "贴片LED" }, - { type: "SevenSegmentDisplay", name: "数码管" }, + { type: "SevenSegmentDisplayUltimate", name: "数码管" }, { type: "HDMI", name: "HDMI接口" }, { type: "DDR", name: "DDR内存" }, { type: "ETH", name: "以太网接口" }, diff --git a/src/components/equipments/SevenSegmentDisplay.vue b/src/components/equipments/SevenSegmentDisplay.vue index 3a5475b..dd5e0b1 100644 --- a/src/components/equipments/SevenSegmentDisplay.vue +++ b/src/components/equipments/SevenSegmentDisplay.vue @@ -1,65 +1,114 @@ @@ -217,12 +266,12 @@ function isSegmentActive( if (isInAfterglowMode.value) { return afterglowStates.value[segment]; } - + // 如果COM口未激活,所有段都不显示 if (!currentComActive.value) { return false; } - + // 否则使用稳定状态 return stableSegmentStates.value[segment]; } @@ -232,7 +281,7 @@ function updateSegmentStates() { // 先获取COM口状态 const comPin = props.pins.find((p) => p.pinId === "COM"); let comActive = false; // 默认未激活 - + if (comPin && comPin.constraint) { const comState = getConstraintState(comPin.constraint); if (props.cathodeType === "anode") { @@ -274,7 +323,8 @@ function updateSegmentStates() { for (const pin of props.pins) { if (["a", "b", "c", "d", "e", "f", "g", "dp"].includes(pin.pinId)) { if (!pin.constraint) { - segmentStates.value[pin.pinId as keyof typeof segmentStates.value] = false; + segmentStates.value[pin.pinId as keyof typeof segmentStates.value] = + false; continue; } const pinState = getConstraintState(pin.constraint); @@ -285,7 +335,8 @@ function updateSegmentStates() { newState = pinState === "low"; } // 段状态只有在COM激活时才有效 - segmentStates.value[pin.pinId as keyof typeof segmentStates.value] = newState; + segmentStates.value[pin.pinId as keyof typeof segmentStates.value] = + newState; } } @@ -328,22 +379,25 @@ function updateAfterglowBuffers() { // 进入余晖模式 function enterAfterglowMode() { isInAfterglowMode.value = true; - + // 保存当前稳定状态作为余晖状态 for (const segmentId of ["a", "b", "c", "d", "e", "f", "g", "dp"]) { const typedSegmentId = segmentId as keyof typeof stableSegmentStates.value; - afterglowStates.value[typedSegmentId] = stableSegmentStates.value[typedSegmentId]; - + afterglowStates.value[typedSegmentId] = + stableSegmentStates.value[typedSegmentId]; + // 设置定时器,在余晖持续时间后退出余晖模式 if (afterglowTimers.value[segmentId]) { clearTimeout(afterglowTimers.value[segmentId]!); } - + afterglowTimers.value[segmentId] = setTimeout(() => { afterglowStates.value[typedSegmentId] = false; - + // 检查是否所有段都已经关闭 - const allSegmentsOff = Object.values(afterglowStates.value).every(state => !state); + const allSegmentsOff = Object.values(afterglowStates.value).every( + (state) => !state, + ); if (allSegmentsOff) { exitAfterglowMode(); } @@ -354,14 +408,14 @@ function enterAfterglowMode() { // 退出余晖模式 function exitAfterglowMode() { isInAfterglowMode.value = false; - + // 清除所有定时器 for (const segmentId of ["a", "b", "c", "d", "e", "f", "g", "dp"]) { if (afterglowTimers.value[segmentId]) { clearTimeout(afterglowTimers.value[segmentId]!); afterglowTimers.value[segmentId] = null; } - + // 重置余晖状态 const typedSegmentId = segmentId as keyof typeof afterglowStates.value; afterglowStates.value[typedSegmentId] = false; @@ -397,11 +451,6 @@ onUnmounted(() => { } } }); - -// 暴露属性和方法 -defineExpose({ - updateSegmentStates, -}); diff --git a/src/components/equipments/SevenSegmentDisplayUltimate.vue b/src/components/equipments/SevenSegmentDisplayUltimate.vue new file mode 100644 index 0000000..681dba4 --- /dev/null +++ b/src/components/equipments/SevenSegmentDisplayUltimate.vue @@ -0,0 +1,413 @@ + + + + + + + diff --git a/src/stores/equipments.ts b/src/stores/equipments.ts index fd959a4..ae95632 100644 --- a/src/stores/equipments.ts +++ b/src/stores/equipments.ts @@ -7,15 +7,21 @@ import { isNumber } from "mathjs"; import { Mutex, withTimeout } from "async-mutex"; import { useConstraintsStore } from "@/stores/constraints"; import { useDialogStore } from "./dialog"; -import { toFileParameterOrUndefined } from "@/utils/Common"; +import { + base64ToArrayBuffer, + toFileParameterOrUndefined, +} from "@/utils/Common"; import { AuthManager } from "@/utils/AuthManager"; -import { HubConnection, HubConnectionBuilder } from "@microsoft/signalr"; +import { HubConnection } from "@microsoft/signalr"; import { getHubProxyFactory, getReceiverRegister, } from "@/utils/signalR/TypedSignalR.Client"; import { ResourcePurpose, type ResourceInfo } from "@/APIClient"; -import type { IJtagHub } from "@/utils/signalR/TypedSignalR.Client/server.Hubs"; +import type { + IDigitalTubesHub, + IJtagHub, +} from "@/utils/signalR/TypedSignalR.Client/server.Hubs"; export const useEquipments = defineStore("equipments", () => { // Global Stores @@ -26,6 +32,7 @@ export const useEquipments = defineStore("equipments", () => { const boardPort = useLocalStorage("fpga-board-port", 1234); // Jtag + const enableJtagBoundaryScan = ref(false); const jtagBitstream = ref(); const jtagBoundaryScanFreq = ref(100); const jtagUserBitstreams = ref([]); @@ -62,46 +69,6 @@ export const useEquipments = defineStore("equipments", () => { } }); - // Matrix Key - const matrixKeyStates = reactive(new Array(16).fill(false)); - const matrixKeypadClientMutex = withTimeout( - new Mutex(), - 1000, - new Error("Matrixkeyclient Mutex Timeout!"), - ); - - // Power - const powerClientMutex = withTimeout( - new Mutex(), - 1000, - new Error("Matrixkeyclient Mutex Timeout!"), - ); - - // Enable Setting - const enableJtagBoundaryScan = ref(false); - const enableMatrixKey = ref(false); - const enablePower = ref(false); - - function setMatrixKey( - keyNum: number | string | undefined, - keyValue: boolean, - ): boolean { - let _keyNum: number; - if (isString(keyNum)) { - _keyNum = toNumber(keyNum); - } else if (isNumber(keyNum)) { - _keyNum = keyNum; - } else { - return false; - } - - if (z.number().nonnegative().max(16).safeParse(_keyNum).success) { - matrixKeyStates[_keyNum] = keyValue; - return true; - } - return false; - } - async function jtagBoundaryScanSetOnOff(enable: boolean) { if (isUndefined(jtagHubProxy.value)) { console.error("JtagHub Not Initialize..."); @@ -223,6 +190,34 @@ export const useEquipments = defineStore("equipments", () => { } } + // Matrix Key + const enableMatrixKey = ref(false); + const matrixKeyStates = reactive(new Array(16).fill(false)); + const matrixKeypadClientMutex = withTimeout( + new Mutex(), + 1000, + new Error("Matrixkeyclient Mutex Timeout!"), + ); + function setMatrixKey( + keyNum: number | string | undefined, + keyValue: boolean, + ): boolean { + let _keyNum: number; + if (isString(keyNum)) { + _keyNum = toNumber(keyNum); + } else if (isNumber(keyNum)) { + _keyNum = keyNum; + } else { + return false; + } + + if (z.number().nonnegative().max(16).safeParse(_keyNum).success) { + matrixKeyStates[_keyNum] = keyValue; + return true; + } + return false; + } + async function matrixKeypadSetKeyStates(keyStates: boolean[]) { const release = await matrixKeypadClientMutex.acquire(); console.log("set Key !!!!!!!!!!!!"); @@ -274,6 +269,13 @@ export const useEquipments = defineStore("equipments", () => { } } + // Power + const powerClientMutex = withTimeout( + new Mutex(), + 1000, + new Error("Matrixkeyclient Mutex Timeout!"), + ); + const enablePower = ref(false); async function powerSetOnOff(enable: boolean) { const release = await powerClientMutex.acquire(); try { @@ -293,6 +295,71 @@ export const useEquipments = defineStore("equipments", () => { } } + // Seven Segment Display + const enableSevenSegmentDisplay = ref(false); + const sevenSegmentDisplayFrequency = ref(100); + const sevenSegmentDisplayData = ref(); + const sevenSegmentDisplayHub = ref(); + const sevenSegmentDisplayHubProxy = ref(); + + async function sevenSegmentDisplaySetOnOff(enable: boolean) { + if (!sevenSegmentDisplayHub.value || !sevenSegmentDisplayHubProxy.value) + return; + await sevenSegmentDisplayHub.value.start(); + + if (enable) { + await sevenSegmentDisplayHubProxy.value.startScan(); + } else { + await sevenSegmentDisplayHubProxy.value.stopScan(); + } + } + + async function sevenSegmentDisplaySetFrequency(frequency: number) { + if (!sevenSegmentDisplayHub.value || !sevenSegmentDisplayHubProxy.value) + return; + await sevenSegmentDisplayHub.value.start(); + + await sevenSegmentDisplayHubProxy.value.setFrequency(frequency); + } + + async function sevenSegmentDisplayGetStatus() { + if (!sevenSegmentDisplayHub.value || !sevenSegmentDisplayHubProxy.value) + return; + await sevenSegmentDisplayHub.value.start(); + + return await sevenSegmentDisplayHubProxy.value.getStatus(); + } + + async function handleSevenSegmentDisplayOnReceive(msg: string) { + const bytes = base64ToArrayBuffer(msg); + sevenSegmentDisplayData.value = new Uint8Array(bytes); + } + + onMounted(async () => { + // 每次挂载都重新创建连接 + sevenSegmentDisplayHub.value = + AuthManager.createAuthenticatedJtagHubConnection(); + sevenSegmentDisplayHubProxy.value = getHubProxyFactory( + "IDigitalTubesHub", + ).createHubProxy(sevenSegmentDisplayHub.value); + + getReceiverRegister("IDigitalTubesReceiver").register( + sevenSegmentDisplayHub.value, + { + onReceive: handleSevenSegmentDisplayOnReceive, + }, + ); + }); + + onUnmounted(() => { + // 断开连接,清理资源 + if (sevenSegmentDisplayHub.value) { + sevenSegmentDisplayHub.value.stop(); + sevenSegmentDisplayHub.value = undefined; + sevenSegmentDisplayHubProxy.value = undefined; + } + }); + return { boardAddr, boardPort, @@ -320,5 +387,13 @@ export const useEquipments = defineStore("equipments", () => { enablePower, powerClientMutex, powerSetOnOff, + + // Seven Segment Display + enableSevenSegmentDisplay, + sevenSegmentDisplayData, + sevenSegmentDisplayFrequency, + sevenSegmentDisplaySetOnOff, + sevenSegmentDisplaySetFrequency, + sevenSegmentDisplayGetStatus, }; }); diff --git a/src/utils/AuthManager.ts b/src/utils/AuthManager.ts index c2f8544..85eaf9a 100644 --- a/src/utils/AuthManager.ts +++ b/src/utils/AuthManager.ts @@ -229,6 +229,15 @@ export class AuthManager { .build(); } + public static createAuthenticatedDigitalTubesHubConnection() { + return new HubConnectionBuilder() + .withUrl("http://127.0.0.1:5000/hubs/DigitalTubesHub", { + accessTokenFactory: () => this.getToken() ?? "", + }) + .withAutomaticReconnect() + .build(); + } + // 登录函数 public static async login( username: string, diff --git a/src/utils/Common.ts b/src/utils/Common.ts index a8ff5cd..a937873 100644 --- a/src/utils/Common.ts +++ b/src/utils/Common.ts @@ -59,3 +59,12 @@ export function formatDate(date: Date | string) { minute: "2-digit", }); } + +export function base64ToArrayBuffer(base64: string) { + var binaryString = atob(base64); + var bytes = new Uint8Array(binaryString.length); + for (var i = 0; i < binaryString.length; i++) { + bytes[i] = binaryString.charCodeAt(i); + } + return bytes.buffer; +} diff --git a/src/utils/signalR/TypedSignalR.Client/index.ts b/src/utils/signalR/TypedSignalR.Client/index.ts index 7992780..cbe2a39 100644 --- a/src/utils/signalR/TypedSignalR.Client/index.ts +++ b/src/utils/signalR/TypedSignalR.Client/index.ts @@ -4,7 +4,7 @@ // @ts-nocheck import type { HubConnection, IStreamResult, Subject } from '@microsoft/signalr'; import type { IDigitalTubesHub, IJtagHub, IProgressHub, IDigitalTubesReceiver, IJtagReceiver, IProgressReceiver } from './server.Hubs'; -import type { ProgressInfo } from '../server.Hubs'; +import type { DigitalTubeTaskStatus, ProgressInfo } from '../server.Hubs'; // components @@ -107,6 +107,10 @@ class IDigitalTubesHub_HubProxy implements IDigitalTubesHub { public readonly setFrequency = async (frequency: number): Promise => { return await this.connection.invoke("SetFrequency", frequency); } + + public readonly getStatus = async (): Promise => { + return await this.connection.invoke("GetStatus"); + } } class IJtagHub_HubProxyFactory implements HubProxyFactory { diff --git a/src/utils/signalR/TypedSignalR.Client/server.Hubs.ts b/src/utils/signalR/TypedSignalR.Client/server.Hubs.ts index fb87cd9..87d4745 100644 --- a/src/utils/signalR/TypedSignalR.Client/server.Hubs.ts +++ b/src/utils/signalR/TypedSignalR.Client/server.Hubs.ts @@ -3,7 +3,7 @@ /* tslint:disable */ // @ts-nocheck import type { IStreamResult, Subject } from '@microsoft/signalr'; -import type { ProgressInfo } from '../server.Hubs'; +import type { DigitalTubeTaskStatus, ProgressInfo } from '../server.Hubs'; export type IDigitalTubesHub = { /** @@ -19,6 +19,10 @@ export type IDigitalTubesHub = { * @returns Transpiled from System.Threading.Tasks.Task */ setFrequency(frequency: number): Promise; + /** + * @returns Transpiled from System.Threading.Tasks.Task + */ + getStatus(): Promise; } export type IJtagHub = { diff --git a/src/utils/signalR/server.Hubs.ts b/src/utils/signalR/server.Hubs.ts index b20811e..4b6b4b6 100644 --- a/src/utils/signalR/server.Hubs.ts +++ b/src/utils/signalR/server.Hubs.ts @@ -2,6 +2,14 @@ /* eslint-disable */ /* tslint:disable */ +/** Transpiled from server.Hubs.DigitalTubeTaskStatus */ +export type DigitalTubeTaskStatus = { + /** Transpiled from int */ + frequency: number; + /** Transpiled from bool */ + isRunning: boolean; +} + /** Transpiled from server.Hubs.ProgressStatus */ export enum ProgressStatus { Pending = 0,