487 lines
17 KiB
C#
487 lines
17 KiB
C#
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;
|
||
}
|
||
|
||
}
|