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.Communication;
namespace RobotConsoleClient
{
@ -6,15 +7,25 @@ namespace RobotConsoleClient
{
static void Main(string[] args)
{
Robot.Instance.Connect("eee...", 1818);
Robot.Instance.Buzzer.Beep(300, 500);
Robot.Instance.Battery.BatteryChanged += Battery_BatteryChanged;
Console.ReadLine();
var com = MqttPublisherSubscriber.Instance;
com.Connect("192.168.20.22", "ADIS", "TEST");
var robotStationary = new Robot(com);
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
{
internal class MqttPublisherSubscriber : IPublisherSubscriber
public class MqttPublisherSubscriber : IPublisherSubscriber
{
private MqttClient client;
private static readonly NLog.Logger log = NLog.LogManager.GetCurrentClassLogger();
@ -29,7 +29,24 @@ namespace RobotLib.Communication
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)
{
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;
lock (clientLock)
@ -46,8 +63,15 @@ namespace RobotLib.Communication
client.ConnectionClosed += Client_ConnectionClosed;
// generate a clientID and connect to Broker
string clientId = Guid.NewGuid().ToString();
var result = client.Connect(clientId);
success = result == 0 ? true : false;
if (String.IsNullOrEmpty(username) || String.IsNullOrEmpty(password))
{
client.Connect(clientId);
}
else
{
client.Connect(clientId, username, password);
}
success = client.IsConnected;
log.Info($"Connecting done. Success = {success}");
}
return success;
@ -79,7 +103,7 @@ namespace RobotLib.Communication
lock (clientLock)
{
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);
}
}
@ -88,8 +112,8 @@ namespace RobotLib.Communication
{
lock (clientLock)
{
var result = client.Publish(topic, Encoding.ASCII.GetBytes(message));
log.Trace($"Published to topic '{topic}'. Message = {message}", result == 0 ? true : false);
var msgId = client.Publish(topic, Encoding.ASCII.GetBytes(message));
log.Trace($"Published to topic '{topic}'. MessageId = {msgId}");
}
}
@ -97,8 +121,8 @@ namespace RobotLib.Communication
{
lock (clientLock)
{
var result = client.Subscribe(new string[] { topic }, new byte[] { MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE });
log.Info($"Subscribed to topic '{topic}'. Success = %s", result == 0 ? true : false);
var msgId = client.Subscribe(new string[] { topic }, new byte[] { MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE });
log.Info($"Subscribed to topic '{topic}'. MessageId = {msgId}");
}
}
}

@ -1,5 +1,6 @@
using RobotLib.Communication;
using System.Collections.Generic;
using System.Diagnostics;
namespace RobotLib
{
@ -7,13 +8,27 @@ namespace RobotLib
{
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>()) { }
/// <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)
{
log = NLog.LogManager.GetLogger(GetType().ToString());
Com = com;
InterestedTopics = interestedTopics;
foreach (var topic in InterestedTopics)
{
this.Com.Subscribe(topic);
}
com.NewMessageArrived += Com_NewMessageArrived;
}

@ -6,54 +6,54 @@ using System.Threading.Tasks;
namespace RobotLib
{
public class DevBattery : DevBase
{
private float voltage;
public event EventHandler<BatteryEventArgs> 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;
}
//public class DevBattery : DevBase
//{
// private float voltage;
// public event EventHandler<BatteryEventArgs> 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;
// }
}
}
// }
//}
}

@ -6,13 +6,13 @@ using System.Threading.Tasks;
namespace RobotLib
{
public class DevBuzzer : DevBase
{
public DevBuzzer(Com com) : base(com) { }
//public class DevBuzzer : DevBase
//{
// public DevBuzzer(Com com) : base(com) { }
public void Beep(int freq, int timeMs)
{
SendMessage($"robo sendcmd buzzer buzz {freq} {timeMs}!");
}
}
// public void Beep(int freq, int 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
{
public class Robot
{
public static Robot Instance { get; } = new Robot();
private Robot()
public Robot(IPublisherSubscriber com)
{
Com = new Com();
Buzzer = new DevBuzzer(Com);
Battery = new DevBattery(Com);
Com = com;
//Buzzer = new DevBuzzer(Com);
//Battery = new DevBattery(Com);
SplitFlap = new DevSplitFlap(com);
Timer timer = new Timer(TimerCallback);
timer.Change(2000, 10000);
}
public Com Com { get; }
public DevBuzzer Buzzer { get; }
public DevBattery Battery { get; }
public IPublisherSubscriber Com { get; }
//public DevBuzzer Buzzer { get; }
//public DevBattery Battery { get; }
public DevSplitFlap SplitFlap { get; }
public void Connect(string host, int port)
{
Com.Connect(host, port);
//Com.Connect(host, port);
}
public void Disconnect()
{
Com.Disconnect();
//Com.Disconnect();
}
private void TimerCallback(object state)
{
if (Com.IsConnected)
{
Battery.Refresh();
//Battery.Refresh();
}
}

@ -1,15 +1,11 @@
using RobotLib.Communication;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
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_CONFIGURE_SF = "/splitFlap/config/setup/";
@ -26,7 +22,7 @@ namespace RobotLib.DevSplitFlap
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);
}
@ -40,18 +36,17 @@ namespace RobotLib.DevSplitFlap
{
if(fromTopic == TOPIC_DISPLAY)
{
string parsedMessage = (string)GetValueFromMesage("message", message);
var parsedMessage = GetValueFromMesage<string>("message", message);
if (parsedMessage == null) parsedMessage = "?";
SplitFlapDisplayEventArgs eventArgs = new(parsedMessage);
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);
object value = null;
data.TryGetValue(parameter, out value);
var data = JsonSerializer.Deserialize<Dictionary<string, T>>(message);
data.TryGetValue(parameter, out T value);
return value;
}
}

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