C#
Full example for a direct connection to LA4 at 192.168.0.23:5000. A background task listens for incoming events, a background thread sends periodic heartbeats, and the main thread sends commands.
note
This example assumes LA4 is reachable at a known static IP. If you are not using a direct or static IP setup, you will need to scan the local network to discover LA4's address before connecting. See the network setup section for details.
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Text.Json;
public class LA4Client
{
private const string LA4_IP = "192.168.0.23";
private const int LA4_PORT = 5000;
private const string MY_IP = "192.168.0.100"; // IP of this machine — LA4 will reply here
private const int MY_PORT = 5000; // Port this machine listens on
private const int HEARTBEAT_FREQUENCY_SECONDS = 3;
private const int SEND_DATA_TIMEOUT_SECONDS = 2;
private readonly string _senderId = Guid.NewGuid().ToString("N")[..8];
private const string SenderName = "My PC App";
private const string SenderVersion = "0.1.0";
private bool _running = true;
public async Task RunAsync()
{
Task.Run(() => StartListenerAsync);
Task.Run(() => SendHeartbeats);
// Wait for listener to start before sending commands
await Task.Delay(500);
await TurnOnModelLightAsync();
Console.WriteLine("Press Enter to exit...");
Console.ReadLine();
_running = false;
}
private async Task SendAsync(object payload)
{
using var client = new TcpClient();
await client.ConnectAsync(LA4_IP, LA4_PORT);
using var stream = client.GetStream();
var json = JsonSerializer.Serialize(payload);
await stream.WriteAsync(Encoding.UTF8.GetBytes(json));
}
private object BuildPayload(string? type = null, string? command = null)
{
return new
{
id = _senderId,
name = SenderName,
ip = MY_IP,
port = MY_PORT,
version = SenderVersion,
coordinator = true,
type_= type,
command,
};
}
private async Task SendCommandAsync(string command)
{
await SendAsync(BuildPayload(type: "cmd", command: command));
}
private async Task TurnOnModelLightAsync()
{
const string sequence = "LED_FAN,1\\nMODEL_LIGHT,80";
var shellCommand =
$"echo \"{sequence}\" > /home/rigsters/la4_sequence.csv" +
" && boardiocli uSeq && boardiocli runSeq";
await SendCommandAsync(shellCommand);
}
private void SendHeartbeats()
{
while (_running)
{
try
{
using var client = new TcpClient();
var result = client.BeginConnect(LA4_IP, LA4_PORT, null, null);
var success = result.AsyncWaitHandle.WaitOne(
TimeSpan.FromSeconds(SEND_DATA_TIMEOUT_SECONDS)
);
if (success && client.Connected)
{
var heartbeat = BuildPayload();
using var stream = client.GetStream();
var json = JsonSerializer.Serialize(heartbeat);
var data = Encoding.UTF8.GetBytes(json);
stream.Write(data, 0, data.Length);
}
client.Close();
}
catch (SocketException) { }
catch (TimeoutException) { }
catch (Exception e)
{
Console.WriteLine($"Cannot send heartbeat to LA4 - {e.Message}");
}
Thread.Sleep(HEARTBEAT_FREQUENCY_SECONDS * 1000);
}
}
private async Task StartListenerAsync()
{
var listener = new TcpListener(IPAddress.Any, MY_PORT);
listener.Start();
Console.WriteLine($"Listening on port {MY_PORT}...");
while (true)
{
using var client = await listener.AcceptTcpClientAsync();
using var stream = client.GetStream();
using var reader = new StreamReader(stream, Encoding.UTF8);
var json = await reader.ReadToEndAsync();
if (string.IsNullOrWhiteSpace(json))
continue;
JsonElement root;
try
{
root = JsonDocument.Parse(json).RootElement;
}
catch (JsonException)
{
continue;
}
var name = root.TryGetProperty("name", out var n) ? n.GetString() : "unknown";
var type = root.TryGetProperty("type_", out var t) ? t.GetString() : null;
switch (type)
{
case "output":
Console.WriteLine($"[{name}] output: {root.GetProperty("output").GetString()}");
break;
case "message":
Console.WriteLine($"[{name}] message: {root.GetProperty("message").GetString()}");
break;
case "unit_info":
Console.WriteLine(
$"[{name}] unit info — " +
$"firmware: {root.GetProperty("firmware_version").GetString()}, " +
$"boardio: {root.GetProperty("boardio_version").GetString()}, " +
$"unit type: {root.GetProperty("unit_type").GetString()}"
);
break;
}
}
}
}