You need .NET 8 SDK (download). This guide uses a monitor on your LAN with Ethernet enabled and SDCP allowed (wording varies by model).
git clone https://github.com/andrew867/MonitorControlSDK.git
cd MonitorControlSDK
dotnet build MonitorControl.sln -c Release
dotnet test MonitorControl.sln -c ReleaseSDAP is UDP port 53862 — devices broadcast a small packet you can listen for:
dotnet run --project src/MonitorControl.Cli -- discoverNote tcpHost / recommendedControlIPv4 in discover output when the packet lists 0.0.0.0 — use that address for SDCP TCP (see SdapAdvertisementPacket.RecommendedControlIPv4).
SDCP uses TCP port 53484 by default (SdcpConnection.DefaultPort):
dotnet run --project src/MonitorControl.Cli -- vmc --host 192.168.0.10 MODELOptional TCP unit and VMC item (when SDAP shows a unit id or the chassis needs B001h):
dotnet run --project src/MonitorControl.Cli -- vmc --host 192.168.0.10 --sdcp-unit 1 --vmc-item B001 MODELOr the minimal sample:
dotnet run --project samples/Sample.Vmc -- 192.168.0.10 MODEL
dotnet run --project samples/Sample.Vmc -- 192.168.0.10 MODEL --sdcp-unit 1 --vmc-item builtInSDAP on UDP 53862 is still how monitors advertise themselves. UDP SDCP on 53484 is for broadcast shading when your fleet is configured for Group/All (see pvm-740-programmer-manual-synthesis.md):
dotnet run --project src/MonitorControl.Cli -- vmc-broadcast --scope all -- STATset BRIGHTNESS 512
dotnet run --project samples/Sample.UdpVmcBroadcast -- 192.168.1.255using MonitorControl.Clients;
using MonitorControl.Protocol;
using MonitorControl.Transport;
using var tcp = new SdcpConnection("192.168.0.10");
tcp.Open();
var vmc = new VmcClient(tcp)
{
TcpSingleUnitId = 1,
VmcItemNumber = SdcpMessageBuffer.SdcpV3ItemVideoMonitorControlBuiltIn,
};
Console.WriteLine(vmc.GetStatString("MODEL"));dotnet run --project src/MonitorControl.Web --urls http://127.0.0.1:5080Open http://127.0.0.1:5080/ for the browser demo and http://127.0.0.1:5080/swagger for OpenAPI. Details: guide/web-api-and-python-gateway.md.
Optional Python reverse proxy on port 8000: examples/python-service/README.md (proxies /api/* and SSE; WebSocket still uses the .NET port).
If you need on-wire VMC from an ESP32 on the same LAN as the monitor, open the esp32-sdcp-vmc folder in Arduino IDE (sketch monitor_knobs_sdcp.ino plus wifi_sdap_web.ino and config_portal.h). First boot starts a captive portal for WiFi; use the page or SDAP discovery to set the monitor IP (NVS mhost), then use pots/buttons per examples/esp32-sdcp-vmc/README.md. Flow diagrams: diagrams/monitor-control-flows.md.
| Goal | Read next |
|---|---|
| Full-stack narrative (protocols + code + examples) | handbook.md |
| All error codes | reference/sdcp-error-codes.md |
| V3 vs V4 headers, item numbers | reference/sdcp-framing-and-items.md |
VMC STATget / STATset tokens |
reference/vmc-command-surface.md |
| VMS structured commands | reference/vms-overview.md |
| Firmware / VMA | guide/firmware-updates.md |
- Timeout / connection refused: firewall, wrong IP, SDCP disabled on monitor, or incompatible / unexpected firmware path.
- Empty or
(null)VMC: field name not supported on that model, wrong SDCP item (B000vsB001), wrong TCP unit header vs SDAP, partial TCP reads (fixed in current SDK), or password lock (see error codes doc).