uncommented unused files DevBuzzer and DevBattery,

implemented automatic subscription to interested topics in DevCase,
fixed implementation of MqttPublisherSubscriber,
improved DevSplitFlap,
implemented test of MQTT in RobotConsoleClient
main
Jonas Arnold 4 years ago
parent 3b7539e69b
commit d57582994f
  1. 23
      ADIS_Csharp/RobotConsoleClient/Program.cs
  2. 40
      ADIS_Csharp/RobotLib/Communication/MqttPublisherSubscriber.cs
  3. 15
      ADIS_Csharp/RobotLib/DevBase.cs
  4. 96
      ADIS_Csharp/RobotLib/DevBattery.cs
  5. 16
      ADIS_Csharp/RobotLib/DevBuzzer.cs
  6. 31
      ADIS_Csharp/RobotLib/Robot.cs
  7. 19
      ADIS_Csharp/RobotLib/SplitFlap/DevSplitFlap.cs
  8. 2
      ADIS_Csharp/RobotLib/SplitFlap/SplitFlapDisplayEventArgs.cs

@ -1,4 +1,5 @@
using RobotLib; using RobotLib;
using RobotLib.Communication;
namespace RobotConsoleClient namespace RobotConsoleClient
{ {
@ -6,15 +7,25 @@ namespace RobotConsoleClient
{ {
static void Main(string[] args) static void Main(string[] args)
{ {
Robot.Instance.Connect("eee...", 1818); var com = MqttPublisherSubscriber.Instance;
Robot.Instance.Buzzer.Beep(300, 500); com.Connect("192.168.20.22", "ADIS", "TEST");
Robot.Instance.Battery.BatteryChanged += Battery_BatteryChanged; var robotStationary = new Robot(com);
Console.ReadLine(); robotStationary.SplitFlap.SplitFlapDisplayChanged += SplitFlap_SplitFlapDisplayChanged;
//Console.ReadLine();
Thread.Sleep(1000);
robotStationary.SplitFlap.ConfigureSplitflap(1, 21);
Thread.Sleep(1000);
robotStationary.SplitFlap.InitializeAllSplitflaps();
} }
private static void Battery_BatteryChanged(object? sender, BatteryEventArgs e) private static void SplitFlap_SplitFlapDisplayChanged(object? sender, RobotLib.SplitFlap.SplitFlapDisplayEventArgs e)
{ {
Console.WriteLine($"Received Battery Changed event. New Battery voltage = {e.Voltage} V"); Console.WriteLine($"SplitFlap changed Display to '{e.DisplayMessage}'");
} }
//private static void Battery_BatteryChanged(object? sender, BatteryEventArgs e)
//{
// Console.WriteLine($"Received Battery Changed event. New Battery voltage = {e.Voltage} V");
//}
} }
} }

@ -5,7 +5,7 @@ using uPLibrary.Networking.M2Mqtt.Messages;
namespace RobotLib.Communication namespace RobotLib.Communication
{ {
internal class MqttPublisherSubscriber : IPublisherSubscriber public class MqttPublisherSubscriber : IPublisherSubscriber
{ {
private MqttClient client; private MqttClient client;
private static readonly NLog.Logger log = NLog.LogManager.GetCurrentClassLogger(); private static readonly NLog.Logger log = NLog.LogManager.GetCurrentClassLogger();
@ -29,7 +29,24 @@ namespace RobotLib.Communication
private MqttPublisherSubscriber() private MqttPublisherSubscriber()
{ } { }
/// <summary>
/// Connect anonymously to the broker.
/// </summary>
/// <param name="brokerIp">IP of the broker</param>
/// <returns>success</returns>
public bool Connect(string brokerIp) public bool Connect(string brokerIp)
{
return this.Connect(brokerIp, null, null);
}
/// <summary>
/// Connect with username/password to the broker.
/// </summary>
/// <param name="brokerIp">IP of the broker</param>
/// <param name="username">username</param>
/// <param name="password">password</param>
/// <returns>success</returns>
public bool Connect(string brokerIp, string username, string password)
{ {
bool success = false; bool success = false;
lock (clientLock) lock (clientLock)
@ -46,8 +63,15 @@ namespace RobotLib.Communication
client.ConnectionClosed += Client_ConnectionClosed; client.ConnectionClosed += Client_ConnectionClosed;
// generate a clientID and connect to Broker // generate a clientID and connect to Broker
string clientId = Guid.NewGuid().ToString(); string clientId = Guid.NewGuid().ToString();
var result = client.Connect(clientId); if (String.IsNullOrEmpty(username) || String.IsNullOrEmpty(password))
success = result == 0 ? true : false; {
client.Connect(clientId);
}
else
{
client.Connect(clientId, username, password);
}
success = client.IsConnected;
log.Info($"Connecting done. Success = {success}"); log.Info($"Connecting done. Success = {success}");
} }
return success; return success;
@ -79,7 +103,7 @@ namespace RobotLib.Communication
lock (clientLock) lock (clientLock)
{ {
SubscribedMsgArrivedEventArgs eventArgs = new(e.Topic, Encoding.UTF8.GetString(e.Message)); SubscribedMsgArrivedEventArgs eventArgs = new(e.Topic, Encoding.UTF8.GetString(e.Message));
log.Trace($"Message received on topic {eventArgs.Topic}: {eventArgs.Message}"); log.Trace($"Message received on topic {eventArgs.Topic}: \n{eventArgs.Message}");
NewMessageArrived?.Invoke(this, eventArgs); NewMessageArrived?.Invoke(this, eventArgs);
} }
} }
@ -88,8 +112,8 @@ namespace RobotLib.Communication
{ {
lock (clientLock) lock (clientLock)
{ {
var result = client.Publish(topic, Encoding.ASCII.GetBytes(message)); var msgId = client.Publish(topic, Encoding.ASCII.GetBytes(message));
log.Trace($"Published to topic '{topic}'. Message = {message}", result == 0 ? true : false); log.Trace($"Published to topic '{topic}'. MessageId = {msgId}");
} }
} }
@ -97,8 +121,8 @@ namespace RobotLib.Communication
{ {
lock (clientLock) lock (clientLock)
{ {
var result = client.Subscribe(new string[] { topic }, new byte[] { MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE }); var msgId = client.Subscribe(new string[] { topic }, new byte[] { MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE });
log.Info($"Subscribed to topic '{topic}'. Success = %s", result == 0 ? true : false); log.Info($"Subscribed to topic '{topic}'. MessageId = {msgId}");
} }
} }
} }

@ -1,5 +1,6 @@
using RobotLib.Communication; using RobotLib.Communication;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
namespace RobotLib namespace RobotLib
{ {
@ -7,13 +8,27 @@ namespace RobotLib
{ {
protected NLog.Logger log { get; private set; } protected NLog.Logger log { get; private set; }
/// <summary>
/// Creates a base class.
/// </summary>
/// <param name="com">communication instance</param>
public DevBase(IPublisherSubscriber com) : this(com, new List<string>()) { } public DevBase(IPublisherSubscriber com) : this(com, new List<string>()) { }
/// <summary>
/// Creates a base class and initializes interested Topics.
/// </summary>
/// <param name="com">connunication instance</param>
/// <param name="interestedTopics">topics that shall be subscribed to</param>
public DevBase(IPublisherSubscriber com, List<string> interestedTopics) public DevBase(IPublisherSubscriber com, List<string> interestedTopics)
{ {
log = NLog.LogManager.GetLogger(GetType().ToString()); log = NLog.LogManager.GetLogger(GetType().ToString());
Com = com; Com = com;
InterestedTopics = interestedTopics; InterestedTopics = interestedTopics;
foreach (var topic in InterestedTopics)
{
this.Com.Subscribe(topic);
}
com.NewMessageArrived += Com_NewMessageArrived; com.NewMessageArrived += Com_NewMessageArrived;
} }

@ -6,54 +6,54 @@ using System.Threading.Tasks;
namespace RobotLib namespace RobotLib
{ {
public class DevBattery : DevBase //public class DevBattery : DevBase
{ //{
private float voltage; // private float voltage;
public event EventHandler<BatteryEventArgs> BatteryChanged; // public event EventHandler<BatteryEventArgs> BatteryChanged;
public float Voltage // public float Voltage
{ // {
get { return voltage; } // get { return voltage; }
private set // private set
{ // {
// value changed? // // value changed?
if(voltage != value) // if(voltage != value)
{ // {
// set new voltage and raise event // // set new voltage and raise event
voltage = value; // voltage = value;
BatteryChanged?.Invoke(this, new BatteryEventArgs(voltage)); // BatteryChanged?.Invoke(this, new BatteryEventArgs(voltage));
} // }
} // }
} // }
public DevBattery(Com com) : base(com, "battery") { } // public DevBattery(Com com) : base(com, "battery") { }
public override void Refresh() // public override void Refresh()
{ // {
SendMessage("get battery status!"); // SendMessage("get battery status!");
} // }
protected override void ParseMessage(string message) // protected override void ParseMessage(string message)
{ // {
// example message = "Battery: 1.25 V" // // example message = "Battery: 1.25 V"
var keyValue = message.Trim().Split(':'); // var keyValue = message.Trim().Split(':');
string key = keyValue[0].Trim(); // string key = keyValue[0].Trim();
string value = keyValue[1].Trim(); // string value = keyValue[1].Trim();
switch (key) // switch (key)
{ // {
case "battery": // case "battery":
value = value.Trim(' ', 'V'); // value = value.Trim(' ', 'V');
this.Voltage = float.Parse(value); // this.Voltage = float.Parse(value);
break; // break;
default: // default:
log.Warn($"Unkown element {key}: {value} in message {message}"); // log.Warn($"Unkown element {key}: {value} in message {message}");
break; // break;
} // }
} // }
} //}
} }

@ -6,13 +6,13 @@ using System.Threading.Tasks;
namespace RobotLib namespace RobotLib
{ {
public class DevBuzzer : DevBase //public class DevBuzzer : DevBase
{ //{
public DevBuzzer(Com com) : base(com) { } // public DevBuzzer(Com com) : base(com) { }
public void Beep(int freq, int timeMs) // public void Beep(int freq, int timeMs)
{ // {
SendMessage($"robo sendcmd buzzer buzz {freq} {timeMs}!"); // SendMessage($"robo sendcmd buzzer buzz {freq} {timeMs}!");
} // }
} //}
} }

@ -1,44 +1,43 @@
using System.Threading; using RobotLib.Communication;
using RobotLib.SplitFlap;
using System.Threading;
namespace RobotLib namespace RobotLib
{ {
public class Robot public class Robot
{ {
public Robot(IPublisherSubscriber com)
public static Robot Instance { get; } = new Robot();
private Robot()
{ {
Com = new Com(); Com = com;
Buzzer = new DevBuzzer(Com); //Buzzer = new DevBuzzer(Com);
Battery = new DevBattery(Com); //Battery = new DevBattery(Com);
SplitFlap = new DevSplitFlap(com);
Timer timer = new Timer(TimerCallback); Timer timer = new Timer(TimerCallback);
timer.Change(2000, 10000); timer.Change(2000, 10000);
} }
public Com Com { get; } public IPublisherSubscriber Com { get; }
public DevBuzzer Buzzer { get; }
public DevBattery Battery { get; }
//public DevBuzzer Buzzer { get; }
//public DevBattery Battery { get; }
public DevSplitFlap SplitFlap { get; }
public void Connect(string host, int port) public void Connect(string host, int port)
{ {
Com.Connect(host, port); //Com.Connect(host, port);
} }
public void Disconnect() public void Disconnect()
{ {
Com.Disconnect(); //Com.Disconnect();
} }
private void TimerCallback(object state) private void TimerCallback(object state)
{ {
if (Com.IsConnected) if (Com.IsConnected)
{ {
Battery.Refresh(); //Battery.Refresh();
} }
} }

@ -1,15 +1,11 @@
using RobotLib.Communication; using RobotLib.Communication;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.Json; using System.Text.Json;
using System.Threading.Tasks;
namespace RobotLib.DevSplitFlap namespace RobotLib.SplitFlap
{ {
internal class DevSplitFlap : DevBase public class DevSplitFlap : DevBase
{ {
private const string TOPIC_INITALL = "/splitFlap/cmd/init/"; private const string TOPIC_INITALL = "/splitFlap/cmd/init/";
private const string TOPIC_CONFIGURE_SF = "/splitFlap/config/setup/"; private const string TOPIC_CONFIGURE_SF = "/splitFlap/config/setup/";
@ -26,7 +22,7 @@ namespace RobotLib.DevSplitFlap
public void ConfigureSplitflap(int setupId, int hardwareId) public void ConfigureSplitflap(int setupId, int hardwareId)
{ {
string payload = JsonSerializer.Serialize(new Dictionary<string, string>() { { "setupId", setupId.ToString() }, { "hardwareId", hardwareId.ToString() } }); string payload = JsonSerializer.Serialize(new Dictionary<string, int>() { { "setupId", setupId }, { "hardwareId", hardwareId } });
base.SendMessage(TOPIC_CONFIGURE_SF, payload); base.SendMessage(TOPIC_CONFIGURE_SF, payload);
} }
@ -40,18 +36,17 @@ namespace RobotLib.DevSplitFlap
{ {
if(fromTopic == TOPIC_DISPLAY) if(fromTopic == TOPIC_DISPLAY)
{ {
string parsedMessage = (string)GetValueFromMesage("message", message); var parsedMessage = GetValueFromMesage<string>("message", message);
if (parsedMessage == null) parsedMessage = "?"; if (parsedMessage == null) parsedMessage = "?";
SplitFlapDisplayEventArgs eventArgs = new(parsedMessage); SplitFlapDisplayEventArgs eventArgs = new(parsedMessage);
SplitFlapDisplayChanged?.Invoke(this, eventArgs); SplitFlapDisplayChanged?.Invoke(this, eventArgs);
} }
} }
private object GetValueFromMesage(string parameter,string message) private T GetValueFromMesage<T>(string parameter,string message)
{ {
var data = JsonSerializer.Deserialize<Dictionary<string, object>>(message); var data = JsonSerializer.Deserialize<Dictionary<string, T>>(message);
object value = null; data.TryGetValue(parameter, out T value);
data.TryGetValue(parameter, out value);
return value; return value;
} }
} }

@ -1,4 +1,4 @@
namespace RobotLib.DevSplitFlap namespace RobotLib.SplitFlap
{ {
public class SplitFlapDisplayEventArgs public class SplitFlapDisplayEventArgs
{ {
Loading…
Cancel
Save