fix: 修复示波器修改后无法配置的问题;修复无法生成api的问题;feat: 新增全局控制七段数码管
This commit is contained in:
parent
8fbd30e69f
commit
7d3ef598de
|
@ -130,7 +130,7 @@ try
|
||||||
.AllowAnyHeader()
|
.AllowAnyHeader()
|
||||||
);
|
);
|
||||||
options.AddPolicy("SignalR", policy => policy
|
options.AddPolicy("SignalR", policy => policy
|
||||||
.WithOrigins("http://localhost:5173")
|
.WithOrigins([$"http://{Global.LocalHost}:5173", "http://127.0.0.1:5173"])
|
||||||
.AllowAnyHeader()
|
.AllowAnyHeader()
|
||||||
.AllowAnyMethod()
|
.AllowAnyMethod()
|
||||||
.AllowCredentials()
|
.AllowCredentials()
|
||||||
|
|
|
@ -362,7 +362,7 @@ class OscilloscopeCtrl
|
||||||
{
|
{
|
||||||
// 等待WAVE_READY[0]位为1,最多等待50ms(5次x10ms间隔)
|
// 等待WAVE_READY[0]位为1,最多等待50ms(5次x10ms间隔)
|
||||||
var readyResult = await UDPClientPool.ReadAddrWithWait(
|
var readyResult = await UDPClientPool.ReadAddrWithWait(
|
||||||
this.ep, this.taskID, OscilloscopeAddr.WAVE_READY, 0b00, 0x01, 10, 50);
|
this.ep, this.taskID, OscilloscopeAddr.WAVE_READY, 0b01, 0x01, 10, 50);
|
||||||
|
|
||||||
if (!readyResult.IsSuccessful)
|
if (!readyResult.IsSuccessful)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using DotNext;
|
using DotNext;
|
||||||
|
using Tapper;
|
||||||
|
|
||||||
namespace Peripherals.WS2812Client;
|
namespace Peripherals.WS2812Client;
|
||||||
|
|
||||||
|
@ -12,7 +13,8 @@ class WS2812Addr
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// RGB颜色结构体,包含红、绿、蓝三个颜色分量
|
/// RGB颜色结构体,包含红、绿、蓝三个颜色分量
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public struct RGBColor
|
[TranspilationSource]
|
||||||
|
public class RGBColor
|
||||||
{
|
{
|
||||||
public byte Red { get; set; }
|
public byte Red { get; set; }
|
||||||
public byte Green { get; set; }
|
public byte Green { get; set; }
|
||||||
|
@ -84,13 +86,13 @@ public class WS2812Client
|
||||||
{
|
{
|
||||||
if (ledIndex < 0 || ledIndex >= WS2812Addr.LED_COUNT)
|
if (ledIndex < 0 || ledIndex >= WS2812Addr.LED_COUNT)
|
||||||
{
|
{
|
||||||
return new(new ArgumentOutOfRangeException(nameof(ledIndex),
|
return new(new ArgumentOutOfRangeException(nameof(ledIndex),
|
||||||
$"LED index must be between 0 and {WS2812Addr.LED_COUNT - 1}"));
|
$"LED index must be between 0 and {WS2812Addr.LED_COUNT - 1}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MsgBus.IsRunning)
|
if (MsgBus.IsRunning)
|
||||||
MsgBus.UDPServer.ClearUDPData(this.address, this.taskID);
|
MsgBus.UDPServer.ClearUDPData(this.address, this.taskID);
|
||||||
else
|
else
|
||||||
return new(new Exception("Message Bus not work!"));
|
return new(new Exception("Message Bus not work!"));
|
||||||
|
|
||||||
var addr = WS2812Addr.BASE + (UInt32)(ledIndex * 4); // 每个地址32位,步长为4字节
|
var addr = WS2812Addr.BASE + (UInt32)(ledIndex * 4); // 每个地址32位,步长为4字节
|
||||||
|
@ -123,14 +125,14 @@ public class WS2812Client
|
||||||
{
|
{
|
||||||
if (MsgBus.IsRunning)
|
if (MsgBus.IsRunning)
|
||||||
MsgBus.UDPServer.ClearUDPData(this.address, this.taskID);
|
MsgBus.UDPServer.ClearUDPData(this.address, this.taskID);
|
||||||
else
|
else
|
||||||
return new(new Exception("Message Bus not work!"));
|
return new(new Exception("Message Bus not work!"));
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// 一次性读取所有LED数据,每个LED占用4字节,总共128*4=512字节
|
// 一次性读取所有LED数据,每个LED占用4字节,总共128*4=512字节
|
||||||
var ret = await UDPClientPool.ReadAddr4Bytes(this.ep, this.taskID, WS2812Addr.BASE, WS2812Addr.LED_COUNT, this.timeout);
|
var ret = await UDPClientPool.ReadAddr4Bytes(this.ep, this.taskID, WS2812Addr.BASE, WS2812Addr.LED_COUNT, this.timeout);
|
||||||
|
|
||||||
if (!ret.IsSuccessful)
|
if (!ret.IsSuccessful)
|
||||||
{
|
{
|
||||||
logger.Error($"Get all LED colors failed: {ret.Error}");
|
logger.Error($"Get all LED colors failed: {ret.Error}");
|
||||||
|
@ -139,7 +141,7 @@ public class WS2812Client
|
||||||
|
|
||||||
var data = ret.Value;
|
var data = ret.Value;
|
||||||
var expectedLength = WS2812Addr.LED_COUNT * 4; // 128 * 4 = 512 bytes
|
var expectedLength = WS2812Addr.LED_COUNT * 4; // 128 * 4 = 512 bytes
|
||||||
|
|
||||||
if (data.Length < expectedLength)
|
if (data.Length < expectedLength)
|
||||||
{
|
{
|
||||||
var error = new Exception($"Invalid data length: expected {expectedLength} bytes, got {data.Length}");
|
var error = new Exception($"Invalid data length: expected {expectedLength} bytes, got {data.Length}");
|
||||||
|
@ -148,7 +150,7 @@ public class WS2812Client
|
||||||
}
|
}
|
||||||
|
|
||||||
var colors = new RGBColor[WS2812Addr.LED_COUNT];
|
var colors = new RGBColor[WS2812Addr.LED_COUNT];
|
||||||
|
|
||||||
for (int i = 0; i < WS2812Addr.LED_COUNT; i++)
|
for (int i = 0; i < WS2812Addr.LED_COUNT; i++)
|
||||||
{
|
{
|
||||||
var offset = i * 4;
|
var offset = i * 4;
|
||||||
|
@ -156,7 +158,7 @@ public class WS2812Client
|
||||||
var colorData = BitConverter.ToUInt32(data, offset);
|
var colorData = BitConverter.ToUInt32(data, offset);
|
||||||
colors[i] = RGBColor.FromUInt32(colorData);
|
colors[i] = RGBColor.FromUInt32(colorData);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new(colors);
|
return new(colors);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|
|
@ -156,6 +156,7 @@ const [useProvideOscilloscope, useOscilloscopeState] = createInjectionState(
|
||||||
try {
|
try {
|
||||||
const proxy = getHubProxy();
|
const proxy = getHubProxy();
|
||||||
|
|
||||||
|
// console.log("Applying configuration", config);
|
||||||
const success = await proxy.initialize(config);
|
const success = await proxy.initialize(config);
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
|
|
|
@ -66,7 +66,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="divider"></div>
|
<div class="divider"></div>
|
||||||
<h1 class="font-bold text-center text-2xl">外设</h1>
|
<h1 class="font-bold text-center text-2xl">外设</h1>
|
||||||
<div class="flex flex-row justify-center">
|
<div class="flex flex-row justify-between columns-2">
|
||||||
<div class="flex flex-row">
|
<div class="flex flex-row">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
|
@ -76,6 +76,15 @@
|
||||||
/>
|
/>
|
||||||
<p class="mx-2">启用矩阵键盘</p>
|
<p class="mx-2">启用矩阵键盘</p>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex flex-row">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
class="checkbox"
|
||||||
|
:checked="eqps.enableSevenSegmentDisplay"
|
||||||
|
@change="handleSevenSegmentDisplayCheckboxChange"
|
||||||
|
/>
|
||||||
|
<p class="mx-2">启用数码管</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -146,6 +155,15 @@ async function handleMatrixkeyCheckboxChange(event: Event) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function handleSevenSegmentDisplayCheckboxChange(event: Event) {
|
||||||
|
const target = event.target as HTMLInputElement;
|
||||||
|
if (target.checked) {
|
||||||
|
await eqps.sevenSegmentDisplaySetOnOff(true);
|
||||||
|
} else {
|
||||||
|
await eqps.sevenSegmentDisplaySetOnOff(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function toggleJtagBoundaryScan() {
|
async function toggleJtagBoundaryScan() {
|
||||||
eqps.jtagBoundaryScanSetOnOff(!eqps.enableJtagBoundaryScan);
|
eqps.jtagBoundaryScanSetOnOff(!eqps.enableJtagBoundaryScan);
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
|
|
||||||
<!-- 引脚(仅在非数字孪生模式下显示) -->
|
<!-- 引脚(仅在非数字孪生模式下显示) -->
|
||||||
<div
|
<div
|
||||||
v-if="!props.enableDigitalTwin"
|
v-if="!eqps.enableSevenSegmentDisplay"
|
||||||
v-for="pin in props.pins"
|
v-for="pin in props.pins"
|
||||||
:key="pin.pinId"
|
:key="pin.pinId"
|
||||||
:style="{
|
:style="{
|
||||||
|
@ -74,6 +74,12 @@ import { ref, computed, watch, onMounted, onUnmounted } from "vue";
|
||||||
import { useConstraintsStore } from "../../stores/constraints";
|
import { useConstraintsStore } from "../../stores/constraints";
|
||||||
import Pin from "./Pin.vue";
|
import Pin from "./Pin.vue";
|
||||||
import { useEquipments } from "@/stores/equipments";
|
import { useEquipments } from "@/stores/equipments";
|
||||||
|
import { watchEffect } from "vue";
|
||||||
|
import { useRequiredInjection } from "@/utils/Common";
|
||||||
|
import { useComponentManager } from "../LabCanvas";
|
||||||
|
|
||||||
|
const eqps = useEquipments();
|
||||||
|
const componentManger = useRequiredInjection(useComponentManager);
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// Linus式极简数据结构:一个byte解决一切
|
// Linus式极简数据结构:一个byte解决一切
|
||||||
|
@ -82,7 +88,7 @@ import { useEquipments } from "@/stores/equipments";
|
||||||
interface Props {
|
interface Props {
|
||||||
size?: number;
|
size?: number;
|
||||||
color?: string;
|
color?: string;
|
||||||
enableDigitalTwin?: boolean;
|
// enableDigitalTwin?: boolean;
|
||||||
digitalTwinNum?: number;
|
digitalTwinNum?: number;
|
||||||
// afterglowDuration?: number;
|
// afterglowDuration?: number;
|
||||||
cathodeType?: "common" | "anode";
|
cathodeType?: "common" | "anode";
|
||||||
|
@ -97,7 +103,7 @@ interface Props {
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
size: 1,
|
size: 1,
|
||||||
color: "red",
|
color: "red",
|
||||||
enableDigitalTwin: false,
|
// enableDigitalTwin: false,
|
||||||
digitalTwinNum: 1,
|
digitalTwinNum: 1,
|
||||||
afterglowDuration: 500,
|
afterglowDuration: 500,
|
||||||
cathodeType: "common",
|
cathodeType: "common",
|
||||||
|
@ -158,7 +164,7 @@ function isBitSet(byte: number, bit: number): boolean {
|
||||||
}
|
}
|
||||||
|
|
||||||
function isSegmentActive(segmentId: keyof typeof SEGMENT_BITS): boolean {
|
function isSegmentActive(segmentId: keyof typeof SEGMENT_BITS): boolean {
|
||||||
if (props.enableDigitalTwin) {
|
if (eqps.enableSevenSegmentDisplay) {
|
||||||
// 数字孪生模式:余晖优先,然后是当前byte
|
// 数字孪生模式:余晖优先,然后是当前byte
|
||||||
const bit = SEGMENT_BITS[segmentId];
|
const bit = SEGMENT_BITS[segmentId];
|
||||||
return (
|
return (
|
||||||
|
@ -174,18 +180,16 @@ function isSegmentActive(segmentId: keyof typeof SEGMENT_BITS): boolean {
|
||||||
// SignalR数字孪生集成
|
// SignalR数字孪生集成
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
const eqps = useEquipments();
|
|
||||||
|
|
||||||
async function initDigitalTwin() {
|
async function initDigitalTwin() {
|
||||||
if (
|
if (
|
||||||
!props.enableDigitalTwin ||
|
!eqps.enableSevenSegmentDisplay ||
|
||||||
props.digitalTwinNum <= 0 ||
|
props.digitalTwinNum <= 0 ||
|
||||||
props.digitalTwinNum > 31
|
props.digitalTwinNum > 31
|
||||||
)
|
)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
eqps.sevenSegmentDisplaySetOnOff(props.enableDigitalTwin);
|
eqps.sevenSegmentDisplaySetOnOff(eqps.enableSevenSegmentDisplay);
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
`Digital twin initialized for address: ${props.digitalTwinNum}`,
|
`Digital twin initialized for address: ${props.digitalTwinNum}`,
|
||||||
|
@ -205,7 +209,9 @@ watch(
|
||||||
)
|
)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
handleDigitalTwinData(eqps.sevenSegmentDisplayData[props.digitalTwinNum - 1]);
|
handleDigitalTwinData(
|
||||||
|
eqps.sevenSegmentDisplayData[props.digitalTwinNum - 1],
|
||||||
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -265,7 +271,7 @@ const { getConstraintState, onConstraintStateChange } = useConstraintsStore();
|
||||||
let constraintUnsubscribe: (() => void) | null = null;
|
let constraintUnsubscribe: (() => void) | null = null;
|
||||||
|
|
||||||
function updateConstraintStates() {
|
function updateConstraintStates() {
|
||||||
if (props.enableDigitalTwin) return; // 数字孪生模式下忽略约束
|
if (eqps.enableSevenSegmentDisplay) return; // 数字孪生模式下忽略约束
|
||||||
|
|
||||||
// 获取COM状态
|
// 获取COM状态
|
||||||
const comPin = props.pins.find((p) => p.pinId === "COM");
|
const comPin = props.pins.find((p) => p.pinId === "COM");
|
||||||
|
@ -328,7 +334,7 @@ const pinRefs = ref<Record<string, any>>({});
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
if (props.enableDigitalTwin) {
|
if (eqps.enableSevenSegmentDisplay) {
|
||||||
await initDigitalTwin();
|
await initDigitalTwin();
|
||||||
} else {
|
} else {
|
||||||
constraintUnsubscribe = onConstraintStateChange(updateConstraintStates);
|
constraintUnsubscribe = onConstraintStateChange(updateConstraintStates);
|
||||||
|
@ -349,25 +355,24 @@ onUnmounted(() => {
|
||||||
});
|
});
|
||||||
|
|
||||||
// 监听模式切换
|
// 监听模式切换
|
||||||
watch(
|
// watch(
|
||||||
() => [props.enableDigitalTwin],
|
// () => [eqps.enableSevenSegmentDisplay],
|
||||||
async () => {
|
// async () => {
|
||||||
// 清理旧模式
|
// // 清理旧模式
|
||||||
cleanupDigitalTwin();
|
// if (constraintUnsubscribe) {
|
||||||
if (constraintUnsubscribe) {
|
// constraintUnsubscribe();
|
||||||
constraintUnsubscribe();
|
// constraintUnsubscribe = null;
|
||||||
constraintUnsubscribe = null;
|
// }
|
||||||
}
|
|
||||||
|
|
||||||
// 初始化新模式
|
// // 初始化新模式
|
||||||
if (props.enableDigitalTwin) {
|
// if (eqps.enableSevenSegmentDisplay) {
|
||||||
await initDigitalTwin();
|
// await initDigitalTwin();
|
||||||
} else {
|
// } else {
|
||||||
constraintUnsubscribe = onConstraintStateChange(updateConstraintStates);
|
// constraintUnsubscribe = onConstraintStateChange(updateConstraintStates);
|
||||||
updateConstraintStates();
|
// updateConstraintStates();
|
||||||
}
|
// }
|
||||||
},
|
// },
|
||||||
);
|
// );
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
@ -393,7 +398,7 @@ export function getDefaultProps() {
|
||||||
return {
|
return {
|
||||||
size: 1,
|
size: 1,
|
||||||
color: "red",
|
color: "red",
|
||||||
enableDigitalTwin: false,
|
// enableDigitalTwin: false,
|
||||||
digitalTwinNum: 1,
|
digitalTwinNum: 1,
|
||||||
// afterglowDuration: 500,
|
// afterglowDuration: 500,
|
||||||
cathodeType: "common",
|
cathodeType: "common",
|
||||||
|
|
|
@ -313,8 +313,10 @@ export const useEquipments = defineStore("equipments", () => {
|
||||||
|
|
||||||
if (enable) {
|
if (enable) {
|
||||||
await sevenSegmentDisplayHubProxy.value.startScan();
|
await sevenSegmentDisplayHubProxy.value.startScan();
|
||||||
|
enableSevenSegmentDisplay.value = true;
|
||||||
} else {
|
} else {
|
||||||
await sevenSegmentDisplayHubProxy.value.stopScan();
|
await sevenSegmentDisplayHubProxy.value.stopScan();
|
||||||
|
enableSevenSegmentDisplay.value = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
/* THIS (.ts) FILE IS GENERATED BY Tapper */
|
||||||
|
/* eslint-disable */
|
||||||
|
/* tslint:disable */
|
||||||
|
|
||||||
|
/** Transpiled from Database.ResourceTypes */
|
||||||
|
export type ResourceTypes = {
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
/* THIS (.ts) FILE IS GENERATED BY Tapper */
|
||||||
|
/* eslint-disable */
|
||||||
|
/* tslint:disable */
|
||||||
|
|
||||||
|
/** Transpiled from Peripherals.WS2812Client.RGBColor */
|
||||||
|
export type RGBColor = {
|
||||||
|
/** Transpiled from byte */
|
||||||
|
red: number;
|
||||||
|
/** Transpiled from byte */
|
||||||
|
green: number;
|
||||||
|
/** Transpiled from byte */
|
||||||
|
blue: number;
|
||||||
|
}
|
||||||
|
|
|
@ -3,9 +3,10 @@
|
||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import type { HubConnection, IStreamResult, Subject } from '@microsoft/signalr';
|
import type { HubConnection, IStreamResult, Subject } from '@microsoft/signalr';
|
||||||
import type { IDigitalTubesHub, IJtagHub, IOscilloscopeHub, IProgressHub, IRotaryEncoderHub, IDigitalTubesReceiver, IJtagReceiver, IOscilloscopeReceiver, IProgressReceiver, IRotaryEncoderReceiver } from './server.Hubs';
|
import type { IDigitalTubesHub, IJtagHub, IOscilloscopeHub, IProgressHub, IRotaryEncoderHub, IWS2812Hub, IDigitalTubesReceiver, IJtagReceiver, IOscilloscopeReceiver, IProgressReceiver, IRotaryEncoderReceiver, IWS2812Receiver } from './server.Hubs';
|
||||||
import type { DigitalTubeTaskStatus, OscilloscopeFullConfig, OscilloscopeDataResponse, ProgressInfo } from '../server.Hubs';
|
import type { DigitalTubeTaskStatus, OscilloscopeFullConfig, OscilloscopeDataResponse, ProgressInfo } from '../server.Hubs';
|
||||||
import type { RotaryEncoderDirection } from '../Peripherals.RotaryEncoderClient';
|
import type { RotaryEncoderDirection } from '../Peripherals.RotaryEncoderClient';
|
||||||
|
import type { RGBColor } from '../Peripherals.WS2812Client';
|
||||||
|
|
||||||
|
|
||||||
// components
|
// components
|
||||||
|
@ -49,6 +50,7 @@ export type HubProxyFactoryProvider = {
|
||||||
(hubType: "IOscilloscopeHub"): HubProxyFactory<IOscilloscopeHub>;
|
(hubType: "IOscilloscopeHub"): HubProxyFactory<IOscilloscopeHub>;
|
||||||
(hubType: "IProgressHub"): HubProxyFactory<IProgressHub>;
|
(hubType: "IProgressHub"): HubProxyFactory<IProgressHub>;
|
||||||
(hubType: "IRotaryEncoderHub"): HubProxyFactory<IRotaryEncoderHub>;
|
(hubType: "IRotaryEncoderHub"): HubProxyFactory<IRotaryEncoderHub>;
|
||||||
|
(hubType: "IWS2812Hub"): HubProxyFactory<IWS2812Hub>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getHubProxyFactory = ((hubType: string) => {
|
export const getHubProxyFactory = ((hubType: string) => {
|
||||||
|
@ -67,6 +69,9 @@ export const getHubProxyFactory = ((hubType: string) => {
|
||||||
if(hubType === "IRotaryEncoderHub") {
|
if(hubType === "IRotaryEncoderHub") {
|
||||||
return IRotaryEncoderHub_HubProxyFactory.Instance;
|
return IRotaryEncoderHub_HubProxyFactory.Instance;
|
||||||
}
|
}
|
||||||
|
if(hubType === "IWS2812Hub") {
|
||||||
|
return IWS2812Hub_HubProxyFactory.Instance;
|
||||||
|
}
|
||||||
}) as HubProxyFactoryProvider;
|
}) as HubProxyFactoryProvider;
|
||||||
|
|
||||||
export type ReceiverRegisterProvider = {
|
export type ReceiverRegisterProvider = {
|
||||||
|
@ -75,6 +80,7 @@ export type ReceiverRegisterProvider = {
|
||||||
(receiverType: "IOscilloscopeReceiver"): ReceiverRegister<IOscilloscopeReceiver>;
|
(receiverType: "IOscilloscopeReceiver"): ReceiverRegister<IOscilloscopeReceiver>;
|
||||||
(receiverType: "IProgressReceiver"): ReceiverRegister<IProgressReceiver>;
|
(receiverType: "IProgressReceiver"): ReceiverRegister<IProgressReceiver>;
|
||||||
(receiverType: "IRotaryEncoderReceiver"): ReceiverRegister<IRotaryEncoderReceiver>;
|
(receiverType: "IRotaryEncoderReceiver"): ReceiverRegister<IRotaryEncoderReceiver>;
|
||||||
|
(receiverType: "IWS2812Receiver"): ReceiverRegister<IWS2812Receiver>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getReceiverRegister = ((receiverType: string) => {
|
export const getReceiverRegister = ((receiverType: string) => {
|
||||||
|
@ -93,6 +99,9 @@ export const getReceiverRegister = ((receiverType: string) => {
|
||||||
if(receiverType === "IRotaryEncoderReceiver") {
|
if(receiverType === "IRotaryEncoderReceiver") {
|
||||||
return IRotaryEncoderReceiver_Binder.Instance;
|
return IRotaryEncoderReceiver_Binder.Instance;
|
||||||
}
|
}
|
||||||
|
if(receiverType === "IWS2812Receiver") {
|
||||||
|
return IWS2812Receiver_Binder.Instance;
|
||||||
|
}
|
||||||
}) as ReceiverRegisterProvider;
|
}) as ReceiverRegisterProvider;
|
||||||
|
|
||||||
// HubProxy
|
// HubProxy
|
||||||
|
@ -270,6 +279,31 @@ class IRotaryEncoderHub_HubProxy implements IRotaryEncoderHub {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class IWS2812Hub_HubProxyFactory implements HubProxyFactory<IWS2812Hub> {
|
||||||
|
public static Instance = new IWS2812Hub_HubProxyFactory();
|
||||||
|
|
||||||
|
private constructor() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly createHubProxy = (connection: HubConnection): IWS2812Hub => {
|
||||||
|
return new IWS2812Hub_HubProxy(connection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class IWS2812Hub_HubProxy implements IWS2812Hub {
|
||||||
|
|
||||||
|
public constructor(private connection: HubConnection) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly getAllLedColors = async (): Promise<RGBColor[]> => {
|
||||||
|
return await this.connection.invoke("GetAllLedColors");
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly getLedColor = async (ledIndex: number): Promise<RGBColor> => {
|
||||||
|
return await this.connection.invoke("GetLedColor", ledIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Receiver
|
// Receiver
|
||||||
|
|
||||||
|
@ -378,3 +412,24 @@ class IRotaryEncoderReceiver_Binder implements ReceiverRegister<IRotaryEncoderRe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class IWS2812Receiver_Binder implements ReceiverRegister<IWS2812Receiver> {
|
||||||
|
|
||||||
|
public static Instance = new IWS2812Receiver_Binder();
|
||||||
|
|
||||||
|
private constructor() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly register = (connection: HubConnection, receiver: IWS2812Receiver): Disposable => {
|
||||||
|
|
||||||
|
const __onReceive = (...args: [RGBColor[]]) => receiver.onReceive(...args);
|
||||||
|
|
||||||
|
connection.on("OnReceive", __onReceive);
|
||||||
|
|
||||||
|
const methodList: ReceiverMethod[] = [
|
||||||
|
{ methodName: "OnReceive", method: __onReceive }
|
||||||
|
]
|
||||||
|
|
||||||
|
return new ReceiverMethodSubscription(connection, methodList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
import type { IStreamResult, Subject } from '@microsoft/signalr';
|
import type { IStreamResult, Subject } from '@microsoft/signalr';
|
||||||
import type { DigitalTubeTaskStatus, OscilloscopeFullConfig, OscilloscopeDataResponse, ProgressInfo } from '../server.Hubs';
|
import type { DigitalTubeTaskStatus, OscilloscopeFullConfig, OscilloscopeDataResponse, ProgressInfo } from '../server.Hubs';
|
||||||
import type { RotaryEncoderDirection } from '../Peripherals.RotaryEncoderClient';
|
import type { RotaryEncoderDirection } from '../Peripherals.RotaryEncoderClient';
|
||||||
|
import type { RGBColor } from '../Peripherals.WS2812Client';
|
||||||
|
|
||||||
export type IDigitalTubesHub = {
|
export type IDigitalTubesHub = {
|
||||||
/**
|
/**
|
||||||
|
@ -126,6 +127,18 @@ export type IRotaryEncoderHub = {
|
||||||
disableCycleRotateEncoder(): Promise<boolean>;
|
disableCycleRotateEncoder(): Promise<boolean>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type IWS2812Hub = {
|
||||||
|
/**
|
||||||
|
* @returns Transpiled from System.Threading.Tasks.Task<Peripherals.WS2812Client.RGBColor[]?>
|
||||||
|
*/
|
||||||
|
getAllLedColors(): Promise<RGBColor[]>;
|
||||||
|
/**
|
||||||
|
* @param ledIndex Transpiled from int
|
||||||
|
* @returns Transpiled from System.Threading.Tasks.Task<Peripherals.WS2812Client.RGBColor?>
|
||||||
|
*/
|
||||||
|
getLedColor(ledIndex: number): Promise<RGBColor>;
|
||||||
|
}
|
||||||
|
|
||||||
export type IDigitalTubesReceiver = {
|
export type IDigitalTubesReceiver = {
|
||||||
/**
|
/**
|
||||||
* @param data Transpiled from byte[]
|
* @param data Transpiled from byte[]
|
||||||
|
@ -167,3 +180,11 @@ export type IRotaryEncoderReceiver = {
|
||||||
onReceiveRotate(num: number, direction: RotaryEncoderDirection): Promise<void>;
|
onReceiveRotate(num: number, direction: RotaryEncoderDirection): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type IWS2812Receiver = {
|
||||||
|
/**
|
||||||
|
* @param data Transpiled from Peripherals.WS2812Client.RGBColor[]
|
||||||
|
* @returns Transpiled from System.Threading.Tasks.Task
|
||||||
|
*/
|
||||||
|
onReceive(data: RGBColor[]): Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,3 +60,9 @@ export type ProgressInfo = {
|
||||||
errorMessage: string;
|
errorMessage: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Transpiled from server.Hubs.WS2812TaskStatus */
|
||||||
|
export type WS2812TaskStatus = {
|
||||||
|
/** Transpiled from bool */
|
||||||
|
isRunning: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -141,16 +141,14 @@
|
||||||
<div class="form-control">
|
<div class="form-control">
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span class="label-text font-medium">触发电平</span>
|
<span class="label-text font-medium">触发电平</span>
|
||||||
<span class="label-text-alt">{{
|
<span class="label-text-alt">{{ triggerLevel }}</span>
|
||||||
osc.config.triggerLevel
|
|
||||||
}}</span>
|
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="range"
|
type="range"
|
||||||
min="0"
|
min="0"
|
||||||
max="255"
|
max="255"
|
||||||
step="1"
|
step="1"
|
||||||
v-model="osc.config.triggerLevel"
|
v-model="triggerLevel"
|
||||||
class="range range-primary [--range-bg:#2b7fff]"
|
class="range range-primary [--range-bg:#2b7fff]"
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
|
@ -181,16 +179,14 @@
|
||||||
<div class="form-control">
|
<div class="form-control">
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span class="label-text font-medium">水平偏移</span>
|
<span class="label-text font-medium">水平偏移</span>
|
||||||
<span class="label-text-alt">{{
|
<span class="label-text-alt">{{ horizontalShift }}</span>
|
||||||
osc.config.horizontalShift
|
|
||||||
}}</span>
|
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="range"
|
type="range"
|
||||||
min="0"
|
min="0"
|
||||||
max="1000"
|
max="1000"
|
||||||
step="1"
|
step="1"
|
||||||
v-model="osc.config.horizontalShift"
|
v-model="horizontalShift"
|
||||||
class="range range-secondary [--range-bg:#c27aff]"
|
class="range range-secondary [--range-bg:#c27aff]"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -198,16 +194,14 @@
|
||||||
<div class="form-control">
|
<div class="form-control">
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span class="label-text font-medium">抽取率</span>
|
<span class="label-text font-medium">抽取率</span>
|
||||||
<span class="label-text-alt"
|
<span class="label-text-alt">{{ decimationRate }}%</span>
|
||||||
>{{ osc.config.decimationRate }}%</span
|
|
||||||
>
|
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="range"
|
type="range"
|
||||||
min="0"
|
min="0"
|
||||||
max="100"
|
max="100"
|
||||||
step="1"
|
step="1"
|
||||||
v-model="osc.config.decimationRate"
|
v-model="decimationRate"
|
||||||
class="range range-accent [--range-bg:#fb64b6]"
|
class="range range-accent [--range-bg:#fb64b6]"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -215,16 +209,14 @@
|
||||||
<div class="form-control">
|
<div class="form-control">
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span class="label-text font-medium">刷新频率</span>
|
<span class="label-text font-medium">刷新频率</span>
|
||||||
<span class="label-text-alt"
|
<span class="label-text-alt">{{ captureFrequency }}Hz</span>
|
||||||
>{{ osc.config.captureFrequency }}Hz</span
|
|
||||||
>
|
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="range"
|
type="range"
|
||||||
min="1"
|
min="1"
|
||||||
max="1000"
|
max="1000"
|
||||||
step="1"
|
step="1"
|
||||||
v-model="osc.config.captureFrequency"
|
v-model="captureFrequency"
|
||||||
class="range range-info [--range-bg:#51a2ff]"
|
class="range range-info [--range-bg:#51a2ff]"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -334,6 +326,7 @@ import { useOscilloscopeState } from "@/components/Oscilloscope/OscilloscopeMana
|
||||||
import { useRequiredInjection } from "@/utils/Common";
|
import { useRequiredInjection } from "@/utils/Common";
|
||||||
import { ref, computed } from "vue";
|
import { ref, computed } from "vue";
|
||||||
import { watchEffect } from "vue";
|
import { watchEffect } from "vue";
|
||||||
|
import { toNumber } from "lodash";
|
||||||
|
|
||||||
// 使用全局设备配置
|
// 使用全局设备配置
|
||||||
const equipments = useEquipments();
|
const equipments = useEquipments();
|
||||||
|
@ -341,6 +334,23 @@ const equipments = useEquipments();
|
||||||
// 获取示波器状态和操作
|
// 获取示波器状态和操作
|
||||||
const osc = useRequiredInjection(useOscilloscopeState);
|
const osc = useRequiredInjection(useOscilloscopeState);
|
||||||
|
|
||||||
|
const decimationRate = ref(osc.config.decimationRate);
|
||||||
|
watchEffect(() => {
|
||||||
|
osc.config.decimationRate = toNumber(decimationRate.value);
|
||||||
|
});
|
||||||
|
const captureFrequency = ref(osc.config.captureFrequency);
|
||||||
|
watchEffect(() => {
|
||||||
|
osc.config.captureFrequency = toNumber(captureFrequency.value);
|
||||||
|
});
|
||||||
|
const triggerLevel = ref(osc.config.triggerLevel);
|
||||||
|
watchEffect(() => {
|
||||||
|
osc.config.triggerLevel = toNumber(triggerLevel.value);
|
||||||
|
});
|
||||||
|
const horizontalShift = ref(osc.config.horizontalShift);
|
||||||
|
watchEffect(() => {
|
||||||
|
osc.config.horizontalShift = toNumber(horizontalShift.value);
|
||||||
|
});
|
||||||
|
|
||||||
// 计算是否有波形数据
|
// 计算是否有波形数据
|
||||||
const hasWaveformData = computed(() => {
|
const hasWaveformData = computed(() => {
|
||||||
const data = osc.oscData.value;
|
const data = osc.oscData.value;
|
||||||
|
@ -358,6 +368,10 @@ function toggleCapture() {
|
||||||
|
|
||||||
function resetConfiguration() {
|
function resetConfiguration() {
|
||||||
osc.resetConfiguration();
|
osc.resetConfiguration();
|
||||||
|
horizontalShift.value = osc.config.horizontalShift;
|
||||||
|
triggerLevel.value = osc.config.triggerLevel;
|
||||||
|
captureFrequency.value = osc.config.captureFrequency;
|
||||||
|
decimationRate.value = osc.config.decimationRate;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue