Files
ChunilENG/Assets/Scripts/MQTT.cs

297 lines
10 KiB
C#

using Best.HTTP.JSON.LitJson;
using Best.MQTT;
using Best.MQTT.Packets;
using Best.MQTT.Packets.Builders;
using System;
using System.Collections.Generic;
using System.Text;
using Newtonsoft.Json;
using UnityEngine;
using WI;
public class MQTT : Protocol, ISingle, IOptionable
{
MQTTClient client;
[OptionSection]
string mqttClientSetting;
[OptionKey]
string host ="106.247.236.204";
[OptionKey]
string port="8901";
[OptionKey]
string topics= "MES/PDV/BOARD1,MES/PDV/BOARD2,MES/PDV/BOARD3";
private int portData;
private string[] subscriptionTopics;
public event Action<bool> onNotloadData;
public event Action<List<CompleteInfo>> onMachineData;
public event Action<List<WorkShopInfo>> onWorkshopData;
public event Action<List<AlarmInfo>> onAlarmData;
public void Awake()
{
onNotloadData?.Invoke(true);
}
public void Start()
{
MQTTConnect();
}
public void MQTTConnect()
{
Disconnect();
int.TryParse(port, out portData);
subscriptionTopics = topics.Split(",");
SubscriptionTopic(subscriptionTopics[0], onWorkshopData);
SubscriptionTopic(subscriptionTopics[1], onMachineData);
SubscriptionTopic(subscriptionTopics[2], onAlarmData);
//SubscriptionTopic(subscriptionTopics[0], (data) => { });
Connect(host, portData.ToString(), topics);
}
public event Action portParsingError;
public void Connect(string ip, string port, string topics)
{
//Debug.Log($"1MQTT CONNECTING... {ip}:{port} {topics}");
host = ip;
if (!int.TryParse(port, out int pd))
{
portParsingError?.Invoke();
return;
}
this.portData = pd;
subscriptionTopics = topics.Split(',');
//Debug.Log($"2MQTT CONNECTING... {host}:{this.port} {subscriptionTopics.Length}");
Connect();
}
public void Disconnect()
{
client?.CreateDisconnectPacketBuilder()
.WithReasonCode(DisconnectReasonCodes.NormalDisconnection)
.WithReasonString("Bye")
.BeginDisconnect();
}
public void Connect()
{
//Disconnect();
//#if !UNITY_EDITOR
// HTTPManager.RootFolderName = "EdukitDT";
//#endif
client = new MQTTClientBuilder()
//#if !UNITY_WEBGL || UNITY_EDITOR
.WithOptions(new ConnectionOptionsBuilder().WithTCP(host, portData))
//#else
//.WithOptions(new ConnectionOptionsBuilder().WithWebSocket(host, port).WithTLS())
//#endif
.WithEventHandler(OnConnected)
.WithEventHandler(OnStateChange)
.WithEventHandler(OnDisconnected)
.WithEventHandler(OnError)
.CreateClient();
client.BeginConnect(ConnectPacketBuilderCallback);
}
public event Action<MQTTClient> onConnectedEvent;
private void OnConnected(MQTTClient client)
{
//Debug.Log("OnConnected");
for (int i = 0; i < subscriptionTopics.Length; i++)
{
client.AddTopicAlias(subscriptionTopics[i]);
client.CreateSubscriptionBuilder(subscriptionTopics[i])
.WithMessageCallback(OnMessage)
.WithAcknowledgementCallback(OnSubscriptionAcknowledged)
.WithMaximumQoS(QoSLevels.ExactlyOnceDelivery)
.BeginSubscribe();
}
onConnectedEvent?.Invoke(client);
isSuccess = true;
errorMessage = "Connected";
//client.createapplicationmessagebuilder("best_mqtt/test_topic")
// .withpayload("hello mqtt world!")
// .withqos(best.mqtt.packets.qoslevels.exactlyoncedelivery)
// .withcontenttype("text/plain; charset=utf-8")
// .beginpublish();
}
[Serializable]
public class WorkShopInfo
{
public string groupcd;
public string groupnm;
public string mchcnt;
public string planqty;
public string workqty;
public string goodqty;
public string badqty;
public string badrate;
public string progressrate;
}
[Serializable]
public class CompleteInfo
{
public string datagbn;
public string wordno;
public string workdt;
public string daynight;
public string sitecd;
public string wccd;
public string workcd;
public string worknm;
public string workseq;
public string status;
public string statusnm;
public string itemcd;
public string itemdesc;
public string pjtcd;
public string matcd;
public string cycletime;
public string cavity;
public string planqty;
public string goalqty;
public string workqty;
public string goodqty;
public string badqty;
public string badrate;
public string efficiency;
public string progressrate;
public string sttm;
public string totm;
public string goaltime;
public string ptotm;
public string psttm;
public string moldcd;
public string moldseq;
}
[Serializable]
public class AlarmInfo
{
public string ;
public string ;
public string ;
public string ;
public string ;
public string ;
public string ;
}
public List<CompleteInfo> infos = new List<CompleteInfo>();
public List<WorkShopInfo> workShopInfo = new List<WorkShopInfo>();
public List<AlarmInfo> alarmInfo = new List<AlarmInfo>();
public List<string> workerIds = new List<string>();
Dictionary<string, Action<List<CompleteInfo>>> topicSubscriptionTable = new();
Dictionary<string, Action<List<WorkShopInfo>>> workShopTopicTable = new();
Dictionary<string, Action<List<AlarmInfo>>> alarmTopicTable = new();
private void OnMessage(MQTTClient client, SubscriptionTopic topic, string topicName, ApplicationMessage message)
{
// Convert the raw payload to a string
var payload = Encoding.UTF8.GetString(message.Payload.Data, message.Payload.Offset, message.Payload.Count);
//Debug.Log($"Content-Type: '{message.ContentType}' Payload: '{payload}'");
if (topicName == "MES/PDV/BOARD1")
{
List<WorkShopInfo> data = JsonConvert.DeserializeObject<List<WorkShopInfo>>(payload);
workShopInfo = data;
workShopTopicTable[topicName]?.Invoke(data);
}
else if(topicName== "MES/PDV/BOARD2")
{
List<CompleteInfo> data = JsonConvert.DeserializeObject<List<CompleteInfo>>(payload);
infos = data;
topicSubscriptionTable[topicName]?.Invoke(infos);
}
else if (topicName == "MES/PDV/BOARD3")
{
List<AlarmInfo> data = JsonConvert.DeserializeObject<List<AlarmInfo>>(payload);
alarmInfo = data;
alarmTopicTable[topicName]?.Invoke(alarmInfo);
}
}
StringBuilder sb = new StringBuilder();
void Print(List<string> target)
{
foreach(var t in target)
{
sb.AppendLine(t);
}
Debug.Log(sb.ToString());
sb.Clear();
}
public void SubscriptionTopic(string topic, Action<List<CompleteInfo>> callback)
{
if (!topicSubscriptionTable.ContainsKey(topic))
topicSubscriptionTable.Add(topic, null);
topicSubscriptionTable[topic] += callback;
}
public void SubscriptionTopic(string topic, Action<List<WorkShopInfo>> callback)
{
if (!workShopTopicTable.ContainsKey(topic))
workShopTopicTable.Add(topic, null);
workShopTopicTable[topic] += callback;
}
public void SubscriptionTopic(string topic, Action<List<AlarmInfo>> callback)
{
if (!alarmTopicTable.ContainsKey(topic))
alarmTopicTable.Add(topic, null);
alarmTopicTable[topic] += callback;
}
private void OnSubscriptionAcknowledged(MQTTClient client, SubscriptionTopic topic, SubscribeAckReasonCodes reasonCode)
{
// if (reasonCode <= SubscribeAckReasonCodes.GrantedQoS2)
// Debug.Log($"Successfully subscribed with topic filter '{topic.Filter.OriginalFilter}'. QoS granted by the server: {reasonCode}");
// else
// Debug.Log($"Could not subscribe with topic filter '{topic.Filter.OriginalFilter}'! Error code: {reasonCode}");
}
void OnDestroy()
{
//Debug.Log("MQTT DESTROY");
client?.CreateDisconnectPacketBuilder()
.WithReasonCode(DisconnectReasonCodes.NormalDisconnection)
//.WithReasonString("Bye")
.BeginDisconnect();
infos.Clear();
topicSubscriptionTable.Clear();
}
private ConnectPacketBuilder ConnectPacketBuilderCallback(MQTTClient client, ConnectPacketBuilder builder)
{
return builder;
}
public event Action<MQTTClient, string> onErrorEvent;
private void OnError(MQTTClient client, string error)
{
isSuccess = false;
errorMessage = "UnConnected";
//Debug.Log($"OnError! :{error}");
onErrorEvent?.Invoke(client, error);
//throw new NotImplementedException();
}
public event Action<MQTTClient, DisconnectReasonCodes, string> onDisconnectedEvent;
private void OnDisconnected(MQTTClient client, DisconnectReasonCodes reasonCode, string reasonMessage)
{
if (client == null)
{
Debug.Log("Client Missing");
return;
}
onDisconnectedEvent?.Invoke(client, reasonCode, reasonMessage);
}
public event Action<MQTTClient, ClientStates, ClientStates> onStateChangeEvent;
private void OnStateChange(MQTTClient client, ClientStates oldState, ClientStates newState)
{
onStateChangeEvent?.Invoke(client, oldState, newState);
//throw new NotImplementedException();
}
}