using System.ComponentModel;
using System.Text;
using System.Text.RegularExpressions;
using Dabit.Mcp.Services;
using DibdProtocol.Protocol;
using ModelContextProtocol.Server;
namespace Dabit.Mcp.Tools;
///
/// 전광판 상태를 읽는 도구 모음. 모두 읽기 전용 — 표시 내용을 바꾸지 않는다.
///
[McpServerToolType]
public sealed class DisplayStatusTools
{
private readonly LedControlService _led;
public DisplayStatusTools(LedControlService led)
{
_led = led;
}
[McpServerTool]
[Description("연결된 LED 전광판의 펌웨어 정보(모델/버전/현재 화면 크기 등)를 읽는다. 표시 내용은 변경하지 않는다.")]
public async Task GetFirmwareInfo(CancellationToken ct = default)
{
var resp = await _led.SendHexAsync(HexCommand.ReadBoardInfo, [0xF1], ct);
if (resp is null || resp.Data.Length == 0)
return "펌웨어 정보를 읽지 못했습니다 (응답 없음 또는 연결 실패).";
// 응답 data[0] == 0xF1 (요청 마커 에코)이면 건너뛴다 (FirmwareService 선례)
var start = (resp.Data.Length > 1 && resp.Data[0] == 0xF1) ? 1 : 0;
var text = Encoding.ASCII.GetString(resp.Data, start, resp.Data.Length - start).TrimEnd('\0', ' ');
return string.IsNullOrWhiteSpace(text) ? "펌웨어 정보가 비어 있습니다." : text;
}
[McpServerTool]
[Description("전광판의 현재 화면 크기(가로 x 세로 픽셀)를 읽는다. 펌웨어 정보 응답에서 추출한다.")]
public async Task GetScreenSize(CancellationToken ct = default)
{
var info = await GetFirmwareInfo(ct);
// 펌웨어 문자열에서 "96x320" 같은 패턴 추출 (실기 검증 후 정밀화)
var m = Regex.Match(info, @"(\d+)\s*[xX]\s*(\d{2,4})");
return m.Success
? $"화면 크기: 가로 {m.Groups[1].Value} x 세로 {m.Groups[2].Value} 픽셀"
: $"화면 크기를 펌웨어 응답에서 찾지 못했습니다. 원문: {info}";
}
[McpServerTool]
[Description("전광판 컨트롤러의 현재 시각(RTC)을 읽는다.")]
public async Task GetTime(CancellationToken ct = default)
{
var resp = await _led.SendHexAsync(HexCommand.ReadTime, [0x00], ct);
if (resp is null || resp.Data.Length == 0)
return "시간을 읽지 못했습니다 (응답 없음 또는 연결 실패).";
// 응답 7바이트 BCD: [yy, MM, dd, dow, HH, mm, ss] (sync_controller_time과 동일 레이아웃)
var d = resp.Data;
if (d.Length < 7)
return $"시간 응답이 예상보다 짧습니다 (raw {Convert.ToHexString(d)}).";
static int FromBcd(byte b) => (b >> 4) * 10 + (b & 0x0F);
var year = 2000 + FromBcd(d[0]);
return $"컨트롤러 시각: {year}-{FromBcd(d[1]):D2}-{FromBcd(d[2]):D2} {FromBcd(d[4]):D2}:{FromBcd(d[5]):D2}:{FromBcd(d[6]):D2}";
}
[McpServerTool]
[Description("현재 MCP 서버에 설정된 전광판 연결 정보를 반환한다. 실제 통신은 하지 않는다(연결 점검·스모크용).")]
public string GetConnectionStatus()
{
return $"전광판 연결 설정 — {_led.Settings.Describe()}";
}
}