diff --git a/ADIS_Csharp/ADIS_Csharp.sln b/ADIS_Csharp/ADIS_Csharp.sln
index f203fb4..a644936 100644
--- a/ADIS_Csharp/ADIS_Csharp.sln
+++ b/ADIS_Csharp/ADIS_Csharp.sln
@@ -15,7 +15,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sync-Ueb04-NestedMonitor",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sync-Ueb05-LostSignals", "Sync-Ueb05-LostSignals\Sync-Ueb05-LostSignals.csproj", "{8605252D-7232-4E7A-B1E0-BF273947F3CB}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MqttTest", "MqttTest\MqttTest.csproj", "{EB76DC93-79D0-4837-8A49-D825CDE4C6A3}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MqttTest", "MqttTest\MqttTest.csproj", "{EB76DC93-79D0-4837-8A49-D825CDE4C6A3}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RobotLib", "RobotLib\RobotLib.csproj", "{915E2889-F10D-4D02-8313-308F642EC64F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -51,6 +53,10 @@ Global
{EB76DC93-79D0-4837-8A49-D825CDE4C6A3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EB76DC93-79D0-4837-8A49-D825CDE4C6A3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EB76DC93-79D0-4837-8A49-D825CDE4C6A3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {915E2889-F10D-4D02-8313-308F642EC64F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {915E2889-F10D-4D02-8313-308F642EC64F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {915E2889-F10D-4D02-8313-308F642EC64F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {915E2889-F10D-4D02-8313-308F642EC64F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/ADIS_Csharp/RobotLib/BatteryEventArgs.cs b/ADIS_Csharp/RobotLib/BatteryEventArgs.cs
new file mode 100644
index 0000000..fb31787
--- /dev/null
+++ b/ADIS_Csharp/RobotLib/BatteryEventArgs.cs
@@ -0,0 +1,14 @@
+using System;
+
+namespace RobotLib
+{
+ public class BatteryEventArgs : EventArgs
+ {
+ public float Voltage { get; }
+
+ public BatteryEventArgs(float voltage)
+ {
+ Voltage = voltage;
+ }
+ }
+}
diff --git a/ADIS_Csharp/RobotLib/ClassDiagram1.cd b/ADIS_Csharp/RobotLib/ClassDiagram1.cd
new file mode 100644
index 0000000..456eaa1
--- /dev/null
+++ b/ADIS_Csharp/RobotLib/ClassDiagram1.cd
@@ -0,0 +1,35 @@
+
+
+
+
+
+ AAQAAAAAAAAAAAAAAAAAAIAAAAEAAAAAQAAAAAAAAAg=
+ Robot.cs
+
+
+
+
+
+
+
+
+ IAQAAAAAAAAAAAFAAAAACIgAAAAAAAAAAAAAAAAEAAI=
+ Com.cs
+
+
+
+
+
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAA=
+ MessageEventArgs.cs
+
+
+
+
+
+ AAAAAAAAAABAAAAAACAgCAgAAAEAAQAAAAAAAAAAAAA=
+ DevBase.cs
+
+
+
+
\ No newline at end of file
diff --git a/ADIS_Csharp/RobotLib/Com.cs b/ADIS_Csharp/RobotLib/Com.cs
new file mode 100644
index 0000000..389d0d9
--- /dev/null
+++ b/ADIS_Csharp/RobotLib/Com.cs
@@ -0,0 +1,87 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace RobotLib
+{
+ public class Com
+ {
+ private static readonly NLog.Logger log = NLog.LogManager.GetCurrentClassLogger();
+ private UdpClient udpClient;
+ private Thread thread;
+
+ public event EventHandler MessageReveived;
+
+ public Com()
+ {
+ }
+
+ public Com(string host, int port)
+ {
+ Connect(host, port);
+ }
+
+ public bool IsConnected { get; private set; }
+
+
+ public void Connect(string host, int port)
+ {
+ if (!IsConnected)
+ {
+ udpClient = new UdpClient();
+ udpClient.Connect(host, port);
+ IsConnected = true;
+
+ thread = new Thread(Run);
+ thread.IsBackground = true;
+ thread.Start();
+ }
+ }
+
+ public void Disconnect()
+ {
+ IsConnected = false;
+ if (thread != null)
+ {
+ thread.Interrupt();
+ thread.Join();
+ }
+ }
+
+ public void Run()
+ {
+ while(IsConnected)
+ {
+ try
+ {
+ IPEndPoint remote = new IPEndPoint(IPAddress.Any, 0);
+ byte[] dataReceived = udpClient.Receive(ref remote);
+ string msg = Encoding.ASCII.GetString(dataReceived);
+ log.Trace($"Msg received from {remote}: {msg}");
+ MessageReveived?.Invoke(this, new MessageEventArgs(msg));
+ }
+ catch (ThreadInterruptedException)
+ {
+ return;
+ }
+ catch (Exception ex)
+ {
+ log.Fatal(ex, "Exception in Receiver-Thread\r\n" + ex);
+ }
+ }
+ }
+
+ public void SendMsg(string msg)
+ {
+ byte[] data = Encoding.ASCII.GetBytes(msg);
+ udpClient.Send(data, data.Length);
+ log.Trace($"Msg sent to {udpClient.Client.RemoteEndPoint}: {msg}");
+ }
+
+ }
+}
diff --git a/ADIS_Csharp/RobotLib/DevBase.cs b/ADIS_Csharp/RobotLib/DevBase.cs
new file mode 100644
index 0000000..a1ed02b
--- /dev/null
+++ b/ADIS_Csharp/RobotLib/DevBase.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace RobotLib
+{
+ public abstract class DevBase
+ {
+ protected NLog.Logger log { get; private set; }
+
+ public DevBase(Com com) : this(com, string.Empty) { }
+ public DevBase(Com com, string keyword)
+ {
+ log = NLog.LogManager.GetLogger(GetType().ToString());
+
+ Keyword = keyword;
+ Com = com;
+ com.MessageReveived += MessageReveived;
+ }
+
+ protected string Keyword { get; }
+ protected Com Com { get; }
+
+ protected virtual void MessageReveived(object sender, MessageEventArgs e)
+ {
+ if (e.Message.StartsWith(Keyword))
+ {
+ ParseMessage(e.Message);
+ }
+ }
+
+ protected void SendMessage(string message)
+ {
+ if (Com.IsConnected)
+ {
+ log.Trace("Esp32> " + message);
+ Com.SendMsg(message);
+ }
+ else
+ {
+ log.Warn("Not connected! Could not send message: " + message);
+ }
+ }
+ protected virtual void ParseMessage(string message) { }
+
+ public virtual void Refresh() { }
+
+ }
+}
diff --git a/ADIS_Csharp/RobotLib/DevBattery.cs b/ADIS_Csharp/RobotLib/DevBattery.cs
new file mode 100644
index 0000000..d1a7d0b
--- /dev/null
+++ b/ADIS_Csharp/RobotLib/DevBattery.cs
@@ -0,0 +1,59 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace RobotLib
+{
+ public class DevBattery : DevBase
+ {
+ private float voltage;
+
+ public event EventHandler BatteryChanged;
+
+ public float Voltage
+ {
+ get { return voltage; }
+ private set
+ {
+ // value changed?
+ if(voltage != value)
+ {
+ // set new voltage and raise event
+ voltage = value;
+ BatteryChanged?.Invoke(this, new BatteryEventArgs(voltage));
+ }
+ }
+ }
+
+ public DevBattery(Com com) : base(com, "battery") { }
+
+ public override void Refresh()
+ {
+ SendMessage("get battery status!");
+ }
+
+ protected override void ParseMessage(string message)
+ {
+ // example message = "Battery: 1.25 V"
+ var keyValue = message.Trim().Split(':');
+ string key = keyValue[0].Trim();
+ string value = keyValue[1].Trim();
+
+ switch (key)
+ {
+ case "battery":
+ value = value.Trim(' ', 'V');
+ this.Voltage = float.Parse(value);
+ break;
+
+ default:
+ log.Warn($"Unkown element {key}: {value} in message {message}");
+ break;
+ }
+
+
+ }
+ }
+}
diff --git a/ADIS_Csharp/RobotLib/DevBuzzer.cs b/ADIS_Csharp/RobotLib/DevBuzzer.cs
new file mode 100644
index 0000000..dbdb94a
--- /dev/null
+++ b/ADIS_Csharp/RobotLib/DevBuzzer.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace RobotLib
+{
+ public class DevBuzzer : DevBase
+ {
+ public DevBuzzer(Com com) : base(com) { }
+
+ public void Beep(int freq, int timeMs)
+ {
+ SendMessage($"robo sendcmd buzzer buzz {freq} {timeMs}!");
+ }
+ }
+}
diff --git a/ADIS_Csharp/RobotLib/MessageEventArgs.cs b/ADIS_Csharp/RobotLib/MessageEventArgs.cs
new file mode 100644
index 0000000..1582e20
--- /dev/null
+++ b/ADIS_Csharp/RobotLib/MessageEventArgs.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace RobotLib
+{
+ public class MessageEventArgs : EventArgs
+ {
+ public MessageEventArgs(string msg)
+ {
+ Message = msg;
+ }
+
+
+ public string Message { get; }
+ }
+}
diff --git a/ADIS_Csharp/RobotLib/Robot.cs b/ADIS_Csharp/RobotLib/Robot.cs
new file mode 100644
index 0000000..de6e71f
--- /dev/null
+++ b/ADIS_Csharp/RobotLib/Robot.cs
@@ -0,0 +1,46 @@
+using System.Threading;
+
+namespace RobotLib
+{
+ public class Robot
+ {
+
+ public static Robot Instance { get; } = new Robot();
+
+
+ private Robot()
+ {
+ Com = new Com();
+ Buzzer = new DevBuzzer(Com);
+ Battery = new DevBattery(Com);
+
+ Timer timer = new Timer(TimerCallback);
+ timer.Change(2000, 10000);
+ }
+
+ public Com Com { get; }
+
+ public DevBuzzer Buzzer { get; }
+ public DevBattery Battery { get; }
+
+
+ public void Connect(string host, int port)
+ {
+ Com.Connect(host, port);
+ }
+
+ public void Disconnect()
+ {
+ Com.Disconnect();
+ }
+
+ private void TimerCallback(object state)
+ {
+ if (Com.IsConnected)
+ {
+ Battery.Refresh();
+ }
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/ADIS_Csharp/RobotLib/RobotLib.csproj b/ADIS_Csharp/RobotLib/RobotLib.csproj
new file mode 100644
index 0000000..9a8e66f
--- /dev/null
+++ b/ADIS_Csharp/RobotLib/RobotLib.csproj
@@ -0,0 +1,11 @@
+
+
+
+ net6.0
+
+
+
+
+
+
+