using System.ComponentModel; using Dabit.Mcp.Services; using DibdProtocol.Protocol; using Microsoft.Extensions.Logging; using ModelContextProtocol.Server; namespace Dabit.Mcp.Tools; /// 화면 크기·채우기·배경이미지 설정 도구. ⚠️ 쓰기. [McpServerToolType] public sealed class ScreenTools { private readonly LedControlService _led; private readonly ILogger _log; public ScreenTools(LedControlService led, ILogger log) { _led = led; _log = log; } // 색 인덱스 0~7 → RGB332 colorByte (정본 SettingsViewModel, R[2:0]G[5:3]B[7:6]) private static readonly byte[] FillColors = { 0x00, 0x07, 0x38, 0x3F, 0xC0, 0xC7, 0xF8, 0xFF }; private static readonly string[] ColorNames = { "검정", "빨강", "초록", "노랑", "파랑", "분홍", "청록", "하양" }; // bpp 입력(0/1/2) → payload byte (정본: 0→0x02, 2→0x08, 그 외→0x03=3bpp 8색 기본) private static byte BppByte(int bpp) => bpp switch { 0 => 0x02, 2 => 0x08, _ => 0x03 }; [McpServerTool] [Description("전광판 화면 크기(단/열)를 설정한다. ⚠️ 쓰기·설정 저장. layout은 모듈 배열(0~5).")] public async Task SetScreenSize( [Description("단(행) 수 1~16")] int rows, [Description("열 수 1~32")] int cols, [Description("색심도 0/1/2 (기본 1=3bpp 8색)")] int bpp = 1, [Description("배열 0~5 (기본 0)")] int layout = 0, CancellationToken ct = default) { byte[] payload = { BppByte(bpp), (byte)Math.Clamp(rows, 1, 16), (byte)Math.Clamp(cols, 1, 32), (byte)Math.Clamp(layout, 0, 5), 0x00, 0xF1 }; var resp = await _led.SendHexAsync(HexCommand.SetScreenSize, payload, ct, 5000); var (ok, msg) = LedControlService.CheckWriteStatus(HexCommand.SetScreenSize, resp); if (!ok) return $"화면 크기 설정 실패 — {msg}"; // 응답 [0xF1, rows, cols] — 실제 적용된 값 return resp!.Data.Length >= 3 ? $"화면 크기 설정됨: {resp.Data[1]}단 x {resp.Data[2]}열." : "화면 크기 설정됨."; } [McpServerTool] [Description("전광판 전체를 단색으로 채운다. ⚠️ 쓰기 — 현재 화면을 덮어쓴다. color 0~7: 0검정 1빨강 2초록 3노랑 4파랑 5분홍 6청록 7하양.")] public async Task FillScreen( [Description("색 인덱스 0~7 (0검정 1빨강 2초록 3노랑 4파랑 5분홍 6청록 7하양)")] int color, [Description("색심도 0/1/2 (기본 1)")] int bpp = 1, CancellationToken ct = default) { if (color < 0 || color > 7) return "색 인덱스는 0~7이어야 합니다 (0검정 1빨강 2초록 3노랑 4파랑 5분홍 6청록 7하양)."; byte[] payload = { BppByte(bpp), FillColors[color], 0x00, 0x00, 0x00 }; var resp = await _led.SendHexAsync(HexCommand.FillScreen, payload, ct, 5000); var (ok, msg) = LedControlService.CheckWriteStatus(HexCommand.FillScreen, resp); return ok ? $"화면 채움: {ColorNames[color]}." : $"화면 채우기 실패 — {msg}"; } [McpServerTool] [Description("저장된 배경이미지를 불러와 표시한다. ⚠️ 쓰기. num 0~255 (0=사용 안 함).")] public async Task LoadBackgroundImage( [Description("이미지 번호 0~255 (0=사용 안 함)")] int num, CancellationToken ct = default) { if (num < 0 || num > 255) return "이미지 번호는 0~255여야 합니다."; var resp = await _led.SendHexAsync(HexCommand.LoadBackgroundImage, new[] { (byte)num }, ct, 5000); var (ok, msg) = LedControlService.CheckWriteStatus(HexCommand.LoadBackgroundImage, resp); if (!ok) return $"배경이미지 로드 실패 — {msg}"; return num == 0 ? "배경이미지 사용 안 함으로 설정." : $"배경이미지 {num}번 로드."; } }