Advanced Distributed Systems module at HSLU
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

115 lines
6.1 KiB

using System;
using System.Text;
using M2Mqtt;
using M2Mqtt.Messages;
using System.Text.Json;
using System.Linq;
using System.Runtime.CompilerServices;
namespace RaspiControl {
class Programm {
private static MqttClient client;
static void Main(string[] args) {
try {
client = new MqttClient("localhost");
client.MqttMsgPublishReceived += Client_MqttMsgPublishReceived;
string clientId = Guid.NewGuid().ToString();
client.Connect(clientId);
client.Subscribe(new string[] { MqttConstants.DEVICE_STATUS_APP_TOPIC }, new byte[] { MqttMsgBase.QOS_LEVEL_AT_MOST_ONCE });
Joystick joystick = new Joystick();
joystick.JoystickChanged += Joystick_JoystickChanged;
} catch (Exception ex) {
Console.WriteLine(ex.Message);
}
}
private static void Joystick_JoystickChanged(object sender, JoystickEventArgs e) {
switch (e.Button) {
case JoystickButton.None:
break;
case JoystickButton.Left:
client.Publish(MqttConstants.MOBILE_NAV_TURN_TOPIC, Encoding.UTF8.GetBytes($"{NavigationConstants.TURN_ANGLE_LEFT}"), MqttMsgBase.QOS_LEVEL_AT_MOST_ONCE, false);
break;
case JoystickButton.Right:
client.Publish(MqttConstants.MOBILE_NAV_TURN_TOPIC, Encoding.UTF8.GetBytes($"{NavigationConstants.TURN_ANGLE_RIGHT}"), MqttMsgBase.QOS_LEVEL_AT_MOST_ONCE, false);
break;
case JoystickButton.Up:
client.Publish(MqttConstants.MOBILE_NAV_MOVE_TOPIC, Encoding.UTF8.GetBytes($"{NavigationConstants.SPEED_FORWARD}"), MqttMsgBase.QOS_LEVEL_AT_MOST_ONCE, false);
break;
case JoystickButton.Down:
client.Publish(MqttConstants.MOBILE_NAV_MOVE_TOPIC, Encoding.UTF8.GetBytes($"{NavigationConstants.SPEED_BACKWARD}"), MqttMsgBase.QOS_LEVEL_AT_MOST_ONCE, false);
break;
case JoystickButton.Center:
client.Publish(MqttConstants.MOBILE_NAV_STOP_TOPIC, Encoding.UTF8.GetBytes($"{NavigationConstants.STOP}"), MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE, false);
break;
}
}
private static void PublishSplitFlapDisplay(string message) {
string payload = JsonSerializer.Serialize<Dictionary<string, string>>(new Dictionary<string, string>() { { "message", message } });
client.Publish(MqttConstants.SPLITFLAP_DISPLAY, Encoding.UTF8.GetBytes(payload),MqttMsgBase.QOS_LEVEL_AT_MOST_ONCE,false);
}
private static void Client_MqttMsgPublishReceived(object sender, MqttMsgPublishEventArgs e) {
string deviceId = "";
Dictionary<string, object> data;
if (e.Topic.StartsWith(string.Join('/',MqttConstants.DEVICE_STATUS_APP_TOPIC.Split('/').Take(2)))) {
if(e.Topic.EndsWith(MqttConstants.DEVICE_STATUS_APP_TOPIC.Split('/').Last())) {
deviceId = deviceIdFromStatusTopic(e.Topic);
if(deviceId == "mobile") {
try {
data = getValueFromTopic(Encoding.UTF8.GetString(e.Message));
object value;
data.TryGetValue("state", out value);
if (value != null) {
APP_STATE appState = (APP_STATE)Convert.ToUInt16(value.ToString());
switch (appState) {
case APP_STATE.STARTUP:
Console.WriteLine("Startup");
client.Publish(MqttConstants.SPLITFLAP_INIT, new byte[] { }, MqttMsgBase.QOS_LEVEL_AT_MOST_ONCE, false);
break;
case APP_STATE.INIT:
Console.WriteLine("Init");
PublishSplitFlapDisplay("INIT");
break;
case APP_STATE.CALIBRATE:
break;
case APP_STATE.FOLLOW_LINE:
Console.WriteLine("Follow line");
PublishSplitFlapDisplay("AUTO");
break;
case APP_STATE.IDLE:
break;
case APP_STATE.FINAL:
break;
case APP_STATE.READY:
Console.WriteLine("ready");
PublishSplitFlapDisplay("REDY");
break;
default:
throw new ArgumentException();
}
}
} catch(Exception) {
Console.WriteLine($"Invalid payload received: {Encoding.UTF8.GetString(e.Message)}");
}
}
else {
Console.WriteLine($"on topic: {e.Topic} no key with state found! | {Encoding.UTF8.GetString(e.Message)}");
}
}
}
}
private static string deviceIdFromStatusTopic(string statusTopic) {
string[] topic = statusTopic.Split('/');
return topic[topic.Length - 2];
}
private static Dictionary<string, object> getValueFromTopic(string topic) {
return JsonSerializer.Deserialize<Dictionary<string, object>>(topic);
}
}
}