FPGA_WebLab/server/src/Controllers/OscilloscopeController.cs

487 lines
17 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc;
using Peripherals.OscilloscopeClient;
namespace server.Controllers;
/// <summary>
/// 示波器API控制器 - 普通用户权限
/// </summary>
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class OscilloscopeApiController : ControllerBase
{
private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
private readonly Database.UserManager _userManager = new();
/// <summary>
/// 获取示波器实例
/// </summary>
private Oscilloscope? GetOscilloscope()
{
try
{
var userName = User.Identity?.Name;
if (string.IsNullOrEmpty(userName))
return null;
var userRet = _userManager.GetUserByName(userName);
if (!userRet.IsSuccessful || !userRet.Value.HasValue)
return null;
var user = userRet.Value.Value;
if (user.BoardID == Guid.Empty)
return null;
var boardRet = _userManager.GetBoardByID(user.BoardID);
if (!boardRet.IsSuccessful || !boardRet.Value.HasValue)
return null;
var board = boardRet.Value.Value;
return new Oscilloscope(board.IpAddr, board.Port);
}
catch (Exception ex)
{
logger.Error(ex, "获取示波器实例时发生异常");
return null;
}
}
/// <summary>
/// 初始化示波器
/// </summary>
/// <param name="config">示波器配置</param>
/// <returns>操作结果</returns>
[HttpPost("Initialize")]
[EnableCors("Users")]
[ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
public async Task<IActionResult> Initialize([FromBody] OscilloscopeFullConfig config)
{
try
{
if (config == null)
return BadRequest("配置参数不能为空");
if (config.HorizontalShift > 1023)
return BadRequest("水平偏移量必须在0-1023之间");
if (config.DecimationRate > 1023)
return BadRequest("抽样率必须在0-1023之间");
var oscilloscope = GetOscilloscope();
if (oscilloscope == null)
return BadRequest("用户未绑定有效的实验板");
// 首先关闭捕获
var stopResult = await oscilloscope.SetCaptureEnable(false);
if (!stopResult.IsSuccessful)
{
logger.Error($"关闭捕获失败: {stopResult.Error}");
return StatusCode(StatusCodes.Status500InternalServerError, "关闭捕获失败");
}
// 设置触发电平
var levelResult = await oscilloscope.SetTriggerLevel(config.TriggerLevel);
if (!levelResult.IsSuccessful)
{
logger.Error($"设置触发电平失败: {levelResult.Error}");
return StatusCode(StatusCodes.Status500InternalServerError, "设置触发电平失败");
}
// 设置触发边沿
var edgeResult = await oscilloscope.SetTriggerEdge(config.TriggerRisingEdge);
if (!edgeResult.IsSuccessful)
{
logger.Error($"设置触发边沿失败: {edgeResult.Error}");
return StatusCode(StatusCodes.Status500InternalServerError, "设置触发边沿失败");
}
// 设置水平偏移量
var shiftResult = await oscilloscope.SetHorizontalShift(config.HorizontalShift);
if (!shiftResult.IsSuccessful)
{
logger.Error($"设置水平偏移量失败: {shiftResult.Error}");
return StatusCode(StatusCodes.Status500InternalServerError, "设置水平偏移量失败");
}
// 设置抽样率
var rateResult = await oscilloscope.SetDecimationRate(config.DecimationRate);
if (!rateResult.IsSuccessful)
{
logger.Error($"设置抽样率失败: {rateResult.Error}");
return StatusCode(StatusCodes.Status500InternalServerError, "设置抽样率失败");
}
// // 刷新RAM
// if (config.AutoRefreshRAM)
// {
// var refreshResult = await oscilloscope.RefreshRAM();
// if (!refreshResult.IsSuccessful)
// {
// logger.Error($"刷新RAM失败: {refreshResult.Error}");
// return StatusCode(StatusCodes.Status500InternalServerError, "刷新RAM失败");
// }
// }
// 设置捕获开关
var captureResult = await oscilloscope.SetCaptureEnable(config.CaptureEnabled);
if (!captureResult.IsSuccessful)
{
logger.Error($"设置捕获开关失败: {captureResult.Error}");
return StatusCode(StatusCodes.Status500InternalServerError, "设置捕获开关失败");
}
return Ok(true);
}
catch (Exception ex)
{
logger.Error(ex, "初始化示波器时发生异常");
return StatusCode(StatusCodes.Status500InternalServerError, "操作失败,请稍后重试");
}
}
/// <summary>
/// 启动捕获
/// </summary>
/// <returns>操作结果</returns>
[HttpPost("StartCapture")]
[EnableCors("Users")]
[ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
public async Task<IActionResult> StartCapture()
{
try
{
var oscilloscope = GetOscilloscope();
if (oscilloscope == null)
return BadRequest("用户未绑定有效的实验板");
var result = await oscilloscope.SetCaptureEnable(true);
if (!result.IsSuccessful)
{
logger.Error($"启动捕获失败: {result.Error}");
return StatusCode(StatusCodes.Status500InternalServerError, "启动捕获失败");
}
return Ok(result.Value);
}
catch (Exception ex)
{
logger.Error(ex, "启动捕获时发生异常");
return StatusCode(StatusCodes.Status500InternalServerError, "操作失败,请稍后重试");
}
}
/// <summary>
/// 停止捕获
/// </summary>
/// <returns>操作结果</returns>
[HttpPost("StopCapture")]
[EnableCors("Users")]
[ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
public async Task<IActionResult> StopCapture()
{
try
{
var oscilloscope = GetOscilloscope();
if (oscilloscope == null)
return BadRequest("用户未绑定有效的实验板");
var result = await oscilloscope.SetCaptureEnable(false);
if (!result.IsSuccessful)
{
logger.Error($"停止捕获失败: {result.Error}");
return StatusCode(StatusCodes.Status500InternalServerError, "停止捕获失败");
}
return Ok(result.Value);
}
catch (Exception ex)
{
logger.Error(ex, "停止捕获时发生异常");
return StatusCode(StatusCodes.Status500InternalServerError, "操作失败,请稍后重试");
}
}
/// <summary>
/// 获取示波器数据和状态
/// </summary>
/// <returns>示波器数据和状态信息</returns>
[HttpGet("GetData")]
[EnableCors("Users")]
[ProducesResponseType(typeof(OscilloscopeDataResponse), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
public async Task<IActionResult> GetData()
{
try
{
var oscilloscope = GetOscilloscope();
if (oscilloscope == null)
return BadRequest("用户未绑定有效的实验板");
var freqResult = await oscilloscope.GetADFrequency();
var vppResult = await oscilloscope.GetADVpp();
var maxResult = await oscilloscope.GetADMax();
var minResult = await oscilloscope.GetADMin();
var waveformResult = await oscilloscope.GetWaveformData();
if (!freqResult.IsSuccessful)
{
logger.Error($"获取AD采样频率失败: {freqResult.Error}");
return StatusCode(StatusCodes.Status500InternalServerError, "获取AD采样频率失败");
}
if (!vppResult.IsSuccessful)
{
logger.Error($"获取AD采样幅度失败: {vppResult.Error}");
return StatusCode(StatusCodes.Status500InternalServerError, "获取AD采样幅度失败");
}
if (!maxResult.IsSuccessful)
{
logger.Error($"获取AD采样最大值失败: {maxResult.Error}");
return StatusCode(StatusCodes.Status500InternalServerError, "获取AD采样最大值失败");
}
if (!minResult.IsSuccessful)
{
logger.Error($"获取AD采样最小值失败: {minResult.Error}");
return StatusCode(StatusCodes.Status500InternalServerError, "获取AD采样最小值失败");
}
if (!waveformResult.IsSuccessful)
{
logger.Error($"获取波形数据失败: {waveformResult.Error}");
return StatusCode(StatusCodes.Status500InternalServerError, "获取波形数据失败");
}
var response = new OscilloscopeDataResponse
{
ADFrequency = freqResult.Value,
ADVpp = vppResult.Value,
ADMax = maxResult.Value,
ADMin = minResult.Value,
WaveformData = Convert.ToBase64String(waveformResult.Value)
};
return Ok(response);
}
catch (Exception ex)
{
logger.Error(ex, "获取示波器数据时发生异常");
return StatusCode(StatusCodes.Status500InternalServerError, "操作失败,请稍后重试");
}
}
/// <summary>
/// 更新触发参数
/// </summary>
/// <param name="level">触发电平0-255</param>
/// <param name="risingEdge">触发边沿true为上升沿false为下降沿</param>
/// <returns>操作结果</returns>
[HttpPost("UpdateTrigger")]
[EnableCors("Users")]
[ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
public async Task<IActionResult> UpdateTrigger(byte level, bool risingEdge)
{
try
{
var oscilloscope = GetOscilloscope();
if (oscilloscope == null)
return BadRequest("用户未绑定有效的实验板");
// 设置触发电平
var levelResult = await oscilloscope.SetTriggerLevel(level);
if (!levelResult.IsSuccessful)
{
logger.Error($"设置触发电平失败: {levelResult.Error}");
return StatusCode(StatusCodes.Status500InternalServerError, "设置触发电平失败");
}
// 设置触发边沿
var edgeResult = await oscilloscope.SetTriggerEdge(risingEdge);
if (!edgeResult.IsSuccessful)
{
logger.Error($"设置触发边沿失败: {edgeResult.Error}");
return StatusCode(StatusCodes.Status500InternalServerError, "设置触发边沿失败");
}
return Ok(true);
}
catch (Exception ex)
{
logger.Error(ex, "更新触发参数时发生异常");
return StatusCode(StatusCodes.Status500InternalServerError, "操作失败,请稍后重试");
}
}
/// <summary>
/// 更新采样参数
/// </summary>
/// <param name="horizontalShift">水平偏移量0-1023</param>
/// <param name="decimationRate">抽样率0-1023</param>
/// <returns>操作结果</returns>
[HttpPost("UpdateSampling")]
[EnableCors("Users")]
[ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
public async Task<IActionResult> UpdateSampling(ushort horizontalShift, ushort decimationRate)
{
try
{
if (horizontalShift > 1023)
return BadRequest("水平偏移量必须在0-1023之间");
if (decimationRate > 1023)
return BadRequest("抽样率必须在0-1023之间");
var oscilloscope = GetOscilloscope();
if (oscilloscope == null)
return BadRequest("用户未绑定有效的实验板");
// 设置水平偏移量
var shiftResult = await oscilloscope.SetHorizontalShift(horizontalShift);
if (!shiftResult.IsSuccessful)
{
logger.Error($"设置水平偏移量失败: {shiftResult.Error}");
return StatusCode(StatusCodes.Status500InternalServerError, "设置水平偏移量失败");
}
// 设置抽样率
var rateResult = await oscilloscope.SetDecimationRate(decimationRate);
if (!rateResult.IsSuccessful)
{
logger.Error($"设置抽样率失败: {rateResult.Error}");
return StatusCode(StatusCodes.Status500InternalServerError, "设置抽样率失败");
}
return Ok(true);
}
catch (Exception ex)
{
logger.Error(ex, "更新采样参数时发生异常");
return StatusCode(StatusCodes.Status500InternalServerError, "操作失败,请稍后重试");
}
}
/// <summary>
/// 手动刷新RAM
/// </summary>
/// <returns>操作结果</returns>
[HttpPost("RefreshRAM")]
[EnableCors("Users")]
[ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
public async Task<IActionResult> RefreshRAM()
{
try
{
var oscilloscope = GetOscilloscope();
if (oscilloscope == null)
return BadRequest("用户未绑定有效的实验板");
var result = await oscilloscope.RefreshRAM();
if (!result.IsSuccessful)
{
logger.Error($"刷新RAM失败: {result.Error}");
return StatusCode(StatusCodes.Status500InternalServerError, "刷新RAM失败");
}
return Ok(result.Value);
}
catch (Exception ex)
{
logger.Error(ex, "刷新RAM时发生异常");
return StatusCode(StatusCodes.Status500InternalServerError, "操作失败,请稍后重试");
}
}
/// <summary>
/// 示波器完整配置
/// </summary>
public class OscilloscopeFullConfig
{
/// <summary>
/// 是否启动捕获
/// </summary>
public bool CaptureEnabled { get; set; }
/// <summary>
/// 触发电平0-255
/// </summary>
public byte TriggerLevel { get; set; }
/// <summary>
/// 触发边沿true为上升沿false为下降沿
/// </summary>
public bool TriggerRisingEdge { get; set; }
/// <summary>
/// 水平偏移量0-1023
/// </summary>
public ushort HorizontalShift { get; set; }
/// <summary>
/// 抽样率0-1023
/// </summary>
public ushort DecimationRate { get; set; }
/// <summary>
/// 是否自动刷新RAM
/// </summary>
public bool AutoRefreshRAM { get; set; } = true;
}
/// <summary>
/// 示波器状态和数据
/// </summary>
public class OscilloscopeDataResponse
{
/// <summary>
/// AD采样频率
/// </summary>
public uint ADFrequency { get; set; }
/// <summary>
/// AD采样幅度
/// </summary>
public byte ADVpp { get; set; }
/// <summary>
/// AD采样最大值
/// </summary>
public byte ADMax { get; set; }
/// <summary>
/// AD采样最小值
/// </summary>
public byte ADMin { get; set; }
/// <summary>
/// 波形数据Base64编码
/// </summary>
public string WaveformData { get; set; } = string.Empty;
}
}