using NLog; using System; using System.Collections.Generic; using System.Net; using System.Net.Sockets; using System.Text; using System.Text.Json; using System.Threading; namespace ESPServer { class UnitDataReceiver { private readonly Logger logger = LogManager.GetCurrentClassLogger(); UnitsDatabase db; RegistersContainer registers; int port; public UnitDataReceiver(int port, UnitsDatabase db, RegistersContainer registers) { this.db = db; this.port = port; this.registers = registers; } public void Start() { var t = new Thread(new ThreadStart(this.Run)); t.Start(); } private void Run() { UdpClient listener = new UdpClient(port); IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, port); try { logger.Info("Listening for UDP datagrams on port " + port); while (true) { byte[] bytes = listener.Receive(ref groupEP); string t = Encoding.ASCII.GetString(bytes, 0, bytes.Length); logger.Debug("Received: " + t); try { var received = JsonDocument.Parse(t); var id = received.RootElement.GetProperty("id").GetString(); var unit = db.GetUnit(id); if (unit == null) { logger.Info("Packet from unknown unit " + id); unit = db.AddUnit(id); } ProcessUnit(unit, received.RootElement); } catch (Exception e) { logger.Error(e.Message); } } } catch (SocketException e) { Console.WriteLine(e); } finally { listener.Close(); } } private void ProcessUnit(Unit unit, JsonElement data) { var ip = data.GetProperty("ip").GetString(); lock (unit) { unit.ip = ip; foreach (var v in data.EnumerateObject()) { if (v.Name == "id" || v.Name == "ip") continue; var uv = unit.GetValue(v.Name); if (uv == null) { logger.Info("Unit " + unit.id + " unknown value " + v.Name); } else { if (v.Value.ValueKind == JsonValueKind.Null) uv.value = float.NaN; if (v.Value.ValueKind == JsonValueKind.Number) uv.value = v.Value.GetSingle(); else { if (!float.TryParse(v.Value.GetString(), out uv.value)) { uv.value = float.NaN; } } } } FillRegisters(unit); } } private void FillRegisters(Unit unit) { foreach (var uv in unit.values) { registers.SetFloat(unit.baseAddress + uv.Value.addressOffset, uv.Value.value); } } } }