640 lines
21 KiB
C#
640 lines
21 KiB
C#
using Newtonsoft.Json;
|
||
using Newtonsoft.Json.Linq;
|
||
using System;
|
||
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using System.IO;
|
||
using System.Net.WebSockets;
|
||
using System.Text;
|
||
using System.Threading;
|
||
using UnityEngine;
|
||
using static InterfaceManager;
|
||
|
||
public class RobotDataManager : MonoBehaviour
|
||
{
|
||
[Header("响应成功码")]
|
||
public string rtCode = "0";
|
||
|
||
#region 初始化属性
|
||
/// <summary>
|
||
/// 是否初始化数据
|
||
/// </summary>
|
||
private bool init_data;
|
||
/// <summary>
|
||
/// 是否已获取【机器人列表】
|
||
/// </summary>
|
||
private bool get_robot_list_done;
|
||
/// <summary>
|
||
/// 是否已获取【机柜列表】
|
||
/// </summary>
|
||
private bool get_catrbin_list_done;
|
||
/// <summary>
|
||
/// 是否已获取【机器人地图数据】
|
||
/// </summary>
|
||
private bool get_robot_map_done;
|
||
/// <summary>
|
||
/// 是否已获取【定点任务-巡检点列表获取】、【机器人地图数据】
|
||
/// </summary>
|
||
private bool get_data_after_init_robot;
|
||
/// <summary>
|
||
/// 机器人信息接收次数
|
||
/// </summary>
|
||
private int get_info_times = 0;
|
||
#endregion
|
||
|
||
#region 初始化数据
|
||
|
||
/// <summary>
|
||
/// 【机器人列表】数据集合
|
||
/// </summary>
|
||
[Header("【机器人列表】数据集合")] public List<RobotClass> RobotList = new List<RobotClass>();
|
||
/// <summary>
|
||
/// 【机柜列表】数据集合
|
||
/// </summary>
|
||
[Header("【机柜列表】数据集合")] public List<CabinClass> CarbinList = new List<CabinClass>();
|
||
/// <summary>
|
||
/// 【定点任务-巡检点列表】数据集合
|
||
/// </summary>
|
||
[Header("【定点任务-巡检点列表】数据集合")] public List<RobotFixedPointins> RobotFixedPointsins = new List<RobotFixedPointins>();
|
||
/// <summary>
|
||
/// 【机器人地图】数据
|
||
/// </summary>
|
||
[Header("【机器人地图】数据")] public RobotMap RobotMap = new RobotMap();
|
||
/// <summary>
|
||
/// 【机器人任务队列】数据
|
||
/// </summary>
|
||
[Header("【机器人任务队列】数据")] public RobotTask RobotTask = new RobotTask();
|
||
/// <summary>
|
||
/// 【巡检报表数据】
|
||
/// </summary>
|
||
[Header("【巡检报表数据】")] public InsReport InsReport = new InsReport();
|
||
|
||
///// <summary>
|
||
///// 【机器人位置状态信息】数据队列
|
||
///// </summary>
|
||
//public Queue<RobotPos> RobotPosQueue = new Queue<RobotPos>();
|
||
/// <summary>
|
||
/// 【机器人信息】
|
||
/// </summary>
|
||
[Header("【机器人信息】")] public Queue<RobotInfo[]> RobotInfosQueue = new Queue<RobotInfo[]>();
|
||
|
||
#endregion
|
||
|
||
#region 对象
|
||
|
||
/// <summary>
|
||
/// 机器人对象
|
||
/// </summary>
|
||
public RobotObject RobotObject;
|
||
|
||
#endregion
|
||
|
||
// Start is called before the first frame update
|
||
void Start()
|
||
{
|
||
///获取配置信息
|
||
StartCoroutine(GetRequest(Path.Combine(Application.streamingAssetsPath, "robot.txt"), null, null, (_error, _json) =>
|
||
{
|
||
if (_error != null)
|
||
{
|
||
Debug.Log("请求【配置信息】错误:" + _error);
|
||
return;
|
||
}
|
||
JObject _j = JObject.Parse(_json);
|
||
http_ip_address = _j["http"].ToString();
|
||
ws_ip_address = _j["ws"].ToString();
|
||
http_ip_ma_address = _j["http_ma"].ToString();
|
||
isLive = true;
|
||
}));
|
||
}
|
||
|
||
public string _pno;
|
||
// Update is called once per frame
|
||
void Update()
|
||
{
|
||
Init();
|
||
if (Input.GetKeyUp(KeyCode.Y))
|
||
{
|
||
//UsageExample(_pno);
|
||
for (int i = 0; i < RobotFixedPointsins.Count; i++)
|
||
{
|
||
Debug.Log(RobotFixedPointsins[i].pointNo);
|
||
}
|
||
}
|
||
if (Input.GetKeyUp(KeyCode.J))
|
||
{
|
||
UsageExample(_pno);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 需要Start中获取的数据在此执行
|
||
/// 等待Start完成本地文件读取后执行
|
||
/// </summary>
|
||
public void Init()
|
||
{
|
||
if (!init_data && isLive)
|
||
{
|
||
init_data = true;
|
||
Debug.Log("初始化数据");
|
||
|
||
//获取机器人列表
|
||
StartCoroutine(GetRequest(http_ip_address + get_robot_list, request_header, null, (_error, _data) =>
|
||
{
|
||
if (_error != null)
|
||
{
|
||
Debug.Log("请求【机器人列表】错误:" + _error);
|
||
return;
|
||
}
|
||
|
||
var _response = JsonConvert.DeserializeObject<ResponseData>(_data);
|
||
Debug.Log(_response.rtMsg);
|
||
if (_response.rtCode.Equals(rtCode) && _response.rtData is JObject _jobject)
|
||
{
|
||
if (_jobject != null)
|
||
{
|
||
RobotList = _jobject["list"].ToObject<List<RobotClass>>();
|
||
|
||
//实例化实体机器人
|
||
RobotObject.RobotClass = RobotList[0];
|
||
}
|
||
}
|
||
get_robot_list_done = true;
|
||
}));
|
||
|
||
//获取机柜列表
|
||
StartCoroutine(GetRequest(http_ip_address + get_cabin_list, request_header, new Dictionary<string, string>() { { "isExport", "false" }, { "pageSize", "200" } }, (_error, _data) =>
|
||
{
|
||
if (_error != null)
|
||
{
|
||
Debug.Log("请求【机柜列表】错误:" + _error);
|
||
return;
|
||
}
|
||
|
||
var _response = JsonConvert.DeserializeObject<ResponseData>(_data);
|
||
Debug.Log(_response.rtMsg);
|
||
if (_response.rtCode.Equals(rtCode) && _response.rtData is JObject _jobject)
|
||
{
|
||
if (_jobject != null)
|
||
{
|
||
CarbinList = _jobject["list"].ToObject<List<CabinClass>>();
|
||
}
|
||
}
|
||
get_catrbin_list_done = true;
|
||
}));
|
||
|
||
|
||
}
|
||
|
||
if (get_robot_list_done && get_catrbin_list_done && !get_data_after_init_robot)
|
||
{
|
||
get_data_after_init_robot = true;
|
||
|
||
if (RobotList.Count < 1)
|
||
{
|
||
Debug.Log("机器人列表小于1!");
|
||
return;
|
||
}
|
||
|
||
//获取定点任务-巡检点列表
|
||
StartCoroutine(GetRequest(http_ip_address + get_robot_fixed_pointins, request_header, new Dictionary<string, string>() { { "roomId", RobotList[0].roomId }, { "pageSize", "200" } }, (_error, _data) =>
|
||
{
|
||
if (_error != null)
|
||
{
|
||
Debug.Log("请求【定点任务-巡检点列表】错误:" + _error);
|
||
return;
|
||
}
|
||
|
||
var _response = JsonConvert.DeserializeObject<ResponseData>(_data);
|
||
Debug.Log(_response.rtMsg);
|
||
if (_response.rtCode.Equals(rtCode))
|
||
{
|
||
RobotFixedPointsins = JsonConvert.DeserializeObject<List<RobotFixedPointins>>(_response.rtData.ToString());
|
||
}
|
||
get_catrbin_list_done = true;
|
||
}));
|
||
|
||
//获取机器人地图数据
|
||
StartCoroutine(GetRequest(http_ip_address + get_robot_map + RobotObject.RobotClass.robot_id + "/map", request_header, new Dictionary<string, string>() { { "robotId", RobotList[0].robot_id } }, (_error, _data) =>
|
||
{
|
||
if (_error != null)
|
||
{
|
||
Debug.Log("请求【机器人地图数据】错误:" + _error);
|
||
return;
|
||
}
|
||
|
||
var _response = JsonConvert.DeserializeObject<ResponseData>(_data);
|
||
Debug.Log(_response.rtMsg);
|
||
if (_response.rtCode.Equals(rtCode) && _response.rtData is JObject _jobject)
|
||
{
|
||
if (_jobject != null)
|
||
{
|
||
RobotMap = _jobject.ToObject<RobotMap>();
|
||
|
||
//实例化实体机器人的地图数据
|
||
RobotObject.RobotMap = RobotMap;
|
||
}
|
||
}
|
||
get_robot_map_done = true;
|
||
}));
|
||
|
||
//websocket
|
||
WSRobotPos();
|
||
//WSRobotInfo();
|
||
}
|
||
}
|
||
|
||
#region WebSocket数据接收
|
||
|
||
private ClientWebSocket ws_robot_pos;
|
||
|
||
/// <summary>
|
||
/// 【机器人位置状态信息】
|
||
/// </summary>
|
||
private async void WSRobotPos()
|
||
{
|
||
try
|
||
{
|
||
ws_robot_pos = new ClientWebSocket();
|
||
CancellationToken ct = new CancellationToken();
|
||
var url = ws_ip_address + ws_robot_html5 + RobotObject.RobotClass.id;
|
||
Debug.Log(url);
|
||
Uri uri = new Uri(url);
|
||
await ws_robot_pos.ConnectAsync(uri, ct);
|
||
|
||
while (true)
|
||
{
|
||
Debug.Log("111");
|
||
var result = new byte[1024];
|
||
await ws_robot_pos.ReceiveAsync(new ArraySegment<byte>(result), new CancellationToken());
|
||
var str = Encoding.UTF8.GetString(result, 0, result.Length);
|
||
//处理数据
|
||
JObject _jobject = JObject.Parse(str);
|
||
if (_jobject != null && _jobject["msg"] != null)
|
||
{
|
||
if (RobotObject != null)
|
||
{
|
||
RobotPos _robot_pos = JsonConvert.DeserializeObject<RobotPos>(_jobject["msg"].ToString());
|
||
RobotObject.RobotPosQueue.Enqueue(_robot_pos);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Debug.LogError(ex.ToString());
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 【机器人信息】
|
||
/// </summary>
|
||
private async void WSRobotInfo()
|
||
{
|
||
ClientWebSocket ws = new ClientWebSocket();
|
||
CancellationToken ct = new CancellationToken();
|
||
Uri uri = new Uri(ws_ip_address + ws_robot_info);
|
||
await ws.ConnectAsync(uri, ct);
|
||
|
||
while (true)
|
||
{
|
||
if (get_info_times == 0) continue;
|
||
|
||
var result = new byte[1024];
|
||
await ws.ReceiveAsync(new ArraySegment<byte>(result), new CancellationToken());
|
||
var str = Encoding.UTF8.GetString(result, 0, result.Length);
|
||
//处理数据
|
||
RobotInfo[] _robot_info = JsonConvert.DeserializeObject<RobotInfo[]>(str.ToString());
|
||
RobotInfosQueue.Enqueue(_robot_info);
|
||
|
||
get_info_times++;
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
#region 功能点2:下发巡检任务
|
||
|
||
/*
|
||
* 任务描述:
|
||
* 功能:点击机柜,下发巡检任务。
|
||
* 1.【获取机器人任务队列】先看机器人是否正在巡检(没有才下发)
|
||
* 2.【定点任务下发】“pointList“参数中”pointNo “为机柜巡检点,其他参数照抄不动
|
||
* 3.下发后看【获取机器人任务队列】是否巡检完成
|
||
* 4.巡检完成查看【查询巡检报表数据】将“pic“字段的值从” thermal “开始拆分,把thermal后的截取出来,发送到后台进行保存。
|
||
*/
|
||
|
||
/// <summary>
|
||
/// 功能点2调用示例
|
||
/// </summary>
|
||
/// <param name="_point_no">点位编号</param>
|
||
public void UsageExample(string _point_no)
|
||
{
|
||
//开始执行第一步:查询当前是否正在巡检
|
||
GetTaskQueue((_error, _no_task) =>
|
||
{
|
||
if (_error != null)
|
||
{
|
||
Debug.Log(_error);
|
||
return;
|
||
}
|
||
|
||
//判断当前是否正在巡检
|
||
if (!_no_task)
|
||
{
|
||
//如果准备下发巡检任务时正在巡检,则执行如下操作
|
||
Debug.Log("当前正在巡检中!请稍后再试!");
|
||
//ToDo
|
||
//...
|
||
SecondConfirmPanel.DeleteConform(null, "当前正在巡检中!请稍后再试!");
|
||
return;
|
||
}
|
||
|
||
//若未在巡检,执行第二步:下发任务
|
||
PostRobotTask(_point_no, (_error, _post_success) =>
|
||
{
|
||
//判断是否下发成功
|
||
if (_error != null)
|
||
{
|
||
Debug.Log(_error);
|
||
return;
|
||
}
|
||
//下发成功后开始执行第三步:循环查询直至结束任务
|
||
StartCoroutine(Cyclic_GetTaskQuery((_error) =>
|
||
{
|
||
if (_error != null)
|
||
{
|
||
Debug.Log(_error);
|
||
return;
|
||
}
|
||
|
||
//任务结束后执行第四步:查看【查询巡检报表数据】将“pic“字段的值从” thermal “开始拆分,把thermal后的截取出来,发送到后台进行保存
|
||
GetInsReport((_error, _success) =>
|
||
{
|
||
if (_error != null)
|
||
{
|
||
Debug.Log(_error);
|
||
return;
|
||
}
|
||
|
||
Dictionary<string, List<string>> _pics = new Dictionary<string, List<string>>();
|
||
|
||
for (int i = 0; i < InsReport.thermal.Count; i++)
|
||
{
|
||
var _ps = new List<string>();
|
||
var pic1 = InsReport.thermal[i].pic1.Split("thermal")[1];
|
||
var pic2 = InsReport.thermal[i].pic2.Split("thermal")[1];
|
||
var pic3 = InsReport.thermal[i].pic3.Split("thermal")[1];
|
||
var pic4 = InsReport.thermal[i].pic4.Split("thermal")[1];
|
||
var pic5 = InsReport.thermal[i].pic5.Split("thermal")[1];
|
||
var pic6 = InsReport.thermal[i].pic6.Split("thermal")[1];
|
||
var pic7 = InsReport.thermal[i].pic7.Split("thermal")[1];
|
||
|
||
_ps.Add(pic1);
|
||
_ps.Add(pic2);
|
||
_ps.Add(pic3);
|
||
_ps.Add(pic4);
|
||
_ps.Add(pic5);
|
||
_ps.Add(pic6);
|
||
_ps.Add(pic7);
|
||
|
||
_pics.Add(InsReport.thermal[i].id, _ps);
|
||
}
|
||
//ToDo
|
||
//将处理好的数据发送给后台
|
||
//...
|
||
Debug.Log("图片路径处理完成!");
|
||
});
|
||
}));
|
||
});
|
||
});
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取机器人任务列队
|
||
/// </summary>
|
||
/// <param name="_callback">参数1:异常信息;参数2:true->当前未在巡检</param>
|
||
public void GetTaskQueue(Action<string, bool> _callback = null)
|
||
{
|
||
Debug.Log("查询当前巡检状态中...");
|
||
//注意接口地址中最后一个为机器人id,后期根据业务修改机器人id
|
||
StartCoroutine(GetRequest(http_ip_address + get_task_queue + RobotObject.RobotClass.robot_id, request_header, null, (_error, _data) =>
|
||
{
|
||
if (_error != null)
|
||
{
|
||
_callback?.Invoke(_error, false);
|
||
return;
|
||
}
|
||
|
||
var _response = JsonConvert.DeserializeObject<ResponseData>(_data);
|
||
if (_response.rtCode.Equals(rtCode) && _response.rtData is JObject _jobject)
|
||
{
|
||
Debug.Log(_response.rtMsg);
|
||
if (_jobject != null)
|
||
{
|
||
RobotTask = _jobject.ToObject<RobotTask>();
|
||
|
||
//实例化实体机器人的任务数据,注意机器人id是否匹配
|
||
RobotObject.RobotTask = RobotTask;
|
||
|
||
//判断每条 RobotTask.data[].Task_type是否为fixed
|
||
//...如果没有返回True,表示未在巡检,否则返回False
|
||
_callback?.Invoke(null, RobotTask.data == null || RobotTask.data.Count == 0);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
_callback?.Invoke(_response.rtMsg, false);
|
||
}
|
||
}));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 机器人任务下发
|
||
/// </summary>
|
||
public void PostRobotTask(string _point_no, Action<string, bool> _callback = null)
|
||
{
|
||
var p = new PointList();
|
||
p.pointList.Add(new PointNo("2"));
|
||
string _json_data = "{\r\n \"robotIp\": \"192.168.8.198\",\r\n \"pointList\": [" + p.pointList + " ]\r\n}";
|
||
//string _json_data = "{\r\n \"robotIp\": \"192.168.8.198\",\r\n \"pointList\": [\r\n {\r\n \"pointNo\": \"" + _point_no + "\",\r\n \"04\": \"0\",\r\n \"06\": \"0\",\r\n \"01\": \"1\",\r\n \"cabinType\": \"1\",\r\n \"03\": \"0\",\r\n \"05\": \"0\"\r\n }\r\n ]\r\n}";
|
||
|
||
StartCoroutine(PostRequest(http_ip_address + post_robot_fixed_point, _json_data, request_header, (_error, _data) =>
|
||
{
|
||
if (_error != null)
|
||
{
|
||
Debug.Log(_error);
|
||
_callback?.Invoke(_error, false);
|
||
return;
|
||
}
|
||
|
||
var _response = JsonConvert.DeserializeObject<ResponseData>(_data);
|
||
Debug.Log(_response.rtMsg);
|
||
if (_response.rtCode.Equals(rtCode))//返回值匹配表示下发成功
|
||
{
|
||
//下发成功后循环执行获取机器人任务队列,直至任务队列为空后继续执行后续操作
|
||
_callback?.Invoke(null, true);
|
||
}
|
||
else
|
||
{
|
||
_callback?.Invoke(_response.rtMsg, false);
|
||
}
|
||
}));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 执行循环查询等待操作
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public IEnumerator Cyclic_GetTaskQuery(Action<string> _callback = null)
|
||
{
|
||
int _call_time = 0;//调用次数
|
||
int _response_time = 0;//返回次数
|
||
bool _finish = false;//结束循环操作
|
||
int _error_time = 0;
|
||
while (true)
|
||
{
|
||
if (_finish) break;
|
||
|
||
//循环查询异常次数超过一定值,结束查询并跳出循环,避免过多不必要的开销
|
||
if (_error_time > 3)
|
||
{
|
||
_callback?.Invoke("查询异常!");
|
||
break;
|
||
}
|
||
|
||
yield return new WaitForSeconds(3);
|
||
|
||
if (_call_time != _response_time) continue;
|
||
|
||
#region 测试
|
||
|
||
if (_response_time == 3)
|
||
{
|
||
Debug.Log("测试:等待次数过多");
|
||
_callback?.Invoke(null);
|
||
break;
|
||
}
|
||
|
||
#endregion
|
||
|
||
_call_time++;
|
||
Debug.Log("执行第" + _call_time + "次循环");
|
||
GetTaskQueue((_error, _no_task) =>
|
||
{
|
||
if (_error != null)
|
||
{
|
||
_error_time++;
|
||
_response_time++;
|
||
Debug.Log("请求返回第" + _response_time + "次");
|
||
return;
|
||
}
|
||
if (_no_task)
|
||
{
|
||
//当前无任务,结束循环操作
|
||
_finish = true;
|
||
_callback?.Invoke(null);
|
||
}
|
||
else
|
||
{
|
||
//当前任务尚未结束,继续执行循环操作等待任务结束
|
||
_response_time++;
|
||
Debug.Log("请求返回第" + _response_time + "次");
|
||
}
|
||
});
|
||
}
|
||
yield return null;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取巡检报表数据
|
||
/// </summary>
|
||
public void GetInsReport(Action<string, bool> _callback)
|
||
{
|
||
//需补充请求参数,机器人任务队列中的Ins_Id,根据业务筛选具体数据
|
||
StartCoroutine(GetRequest(http_ip_address + get_record_ins_report, request_header, new Dictionary<string, string>() { { "insId", RobotTask.data[0].Ins_Id } }, (_error, _data) =>
|
||
{
|
||
if (_error != null)
|
||
{
|
||
Debug.Log(_error);
|
||
_callback?.Invoke(_error, false);
|
||
return;
|
||
}
|
||
|
||
var _response = JsonConvert.DeserializeObject<ResponseData>(_data);
|
||
if (_response.rtCode.Equals(rtCode) && _response.rtData is JObject _jobject)
|
||
{
|
||
Debug.Log(_response.rtMsg);
|
||
if (_jobject != null)
|
||
{
|
||
InsReport = _jobject.ToObject<InsReport>();
|
||
|
||
_callback?.Invoke(null, true);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
_callback?.Invoke(_response.rtMsg, false);
|
||
}
|
||
}));
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 功能点3:巡检结果查看
|
||
|
||
public void ViewInspectionResults(Action<string, List<Sprite>> _callback)
|
||
{
|
||
//注意补充Token值
|
||
StartCoroutine(GetRequest(http_ip_ma_address + get_inspection, new Dictionary<string, string>() { { "X-Token", "" } }, null, (_error, _data) =>
|
||
{
|
||
if (_error != null)
|
||
{
|
||
Debug.Log(_error);
|
||
_callback?.Invoke(_error, null);
|
||
return;
|
||
}
|
||
|
||
ResponseData_ma response = JsonConvert.DeserializeObject<ResponseData_ma>(_data);
|
||
if (response.message.Equals("操作成功") && response.data is JObject jobject)
|
||
{
|
||
if (response.data != null)
|
||
{
|
||
var inspection_datas = jobject.ToObject<List<InspectionResult>>();
|
||
|
||
var sprites = new List<Sprite>();
|
||
for (int i = 0; i < inspection_datas.Count; i++)
|
||
{
|
||
//base64转图片
|
||
byte[] bytes = Convert.FromBase64String(_data);
|
||
Texture2D text2D = new Texture2D(100, 100);
|
||
text2D.LoadImage(bytes);
|
||
Sprite sprite = Sprite.Create(text2D, new Rect(0, 0, text2D.width, text2D.height), new Vector2(0.5f, 0.5f));
|
||
sprites.Add(sprite);
|
||
}
|
||
_callback?.Invoke(null, sprites);
|
||
}
|
||
}
|
||
}));
|
||
}
|
||
|
||
#endregion
|
||
|
||
private void OnDestroy()
|
||
{
|
||
CloseClientWebSocket();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 关闭ClientWebSocket。
|
||
/// </summary>
|
||
public void CloseClientWebSocket()
|
||
{
|
||
//关闭Socket
|
||
if (ws_robot_pos != null && ws_robot_pos.State == WebSocketState.Open)
|
||
{
|
||
var task = ws_robot_pos.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None);
|
||
task.Wait();
|
||
}
|
||
}
|
||
}
|