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 初始化属性
///
/// 是否初始化数据
///
private bool init_data;
///
/// 是否已获取【机器人列表】
///
private bool get_robot_list_done;
///
/// 是否已获取【机柜列表】
///
private bool get_catrbin_list_done;
///
/// 是否已获取【机器人地图数据】
///
private bool get_robot_map_done;
///
/// 是否已获取【定点任务-巡检点列表获取】、【机器人地图数据】
///
private bool get_data_after_init_robot;
///
/// 机器人信息接收次数
///
private int get_info_times = 0;
#endregion
#region 初始化数据
///
/// 【机器人列表】数据集合
///
[Header("【机器人列表】数据集合")] public List RobotList = new List();
///
/// 【机柜列表】数据集合
///
[Header("【机柜列表】数据集合")] public List CarbinList = new List();
///
/// 【定点任务-巡检点列表】数据集合
///
[Header("【定点任务-巡检点列表】数据集合")] public List RobotFixedPointsins = new List();
///
/// 【机器人地图】数据
///
[Header("【机器人地图】数据")] public RobotMap RobotMap = new RobotMap();
///
/// 【机器人任务队列】数据
///
[Header("【机器人任务队列】数据")] public RobotTask RobotTask = new RobotTask();
///
/// 【巡检报表数据】
///
[Header("【巡检报表数据】")] public InsReport InsReport = new InsReport();
/////
///// 【机器人位置状态信息】数据队列
/////
//public Queue RobotPosQueue = new Queue();
///
/// 【机器人信息】
///
[Header("【机器人信息】")] public Queue RobotInfosQueue = new Queue();
#endregion
#region 对象
///
/// 机器人对象
///
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);
}
}
///
/// 需要Start中获取的数据在此执行
/// 等待Start完成本地文件读取后执行
///
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(_data);
Debug.Log(_response.rtMsg);
if (_response.rtCode.Equals(rtCode) && _response.rtData is JObject _jobject)
{
if (_jobject != null)
{
RobotList = _jobject["list"].ToObject>();
//实例化实体机器人
RobotObject.RobotClass = RobotList[0];
}
}
get_robot_list_done = true;
}));
//获取机柜列表
StartCoroutine(GetRequest(http_ip_address + get_cabin_list, request_header, new Dictionary() { { "isExport", "false" }, { "pageSize", "200" } }, (_error, _data) =>
{
if (_error != null)
{
Debug.Log("请求【机柜列表】错误:" + _error);
return;
}
var _response = JsonConvert.DeserializeObject(_data);
Debug.Log(_response.rtMsg);
if (_response.rtCode.Equals(rtCode) && _response.rtData is JObject _jobject)
{
if (_jobject != null)
{
CarbinList = _jobject["list"].ToObject>();
}
}
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() { { "roomId", RobotList[0].roomId }, { "pageSize", "200" } }, (_error, _data) =>
{
if (_error != null)
{
Debug.Log("请求【定点任务-巡检点列表】错误:" + _error);
return;
}
var _response = JsonConvert.DeserializeObject(_data);
Debug.Log(_response.rtMsg);
if (_response.rtCode.Equals(rtCode))
{
RobotFixedPointsins = JsonConvert.DeserializeObject>(_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() { { "robotId", RobotList[0].robot_id } }, (_error, _data) =>
{
if (_error != null)
{
Debug.Log("请求【机器人地图数据】错误:" + _error);
return;
}
var _response = JsonConvert.DeserializeObject(_data);
Debug.Log(_response.rtMsg);
if (_response.rtCode.Equals(rtCode) && _response.rtData is JObject _jobject)
{
if (_jobject != null)
{
RobotMap = _jobject.ToObject();
//实例化实体机器人的地图数据
RobotObject.RobotMap = RobotMap;
}
}
get_robot_map_done = true;
}));
//websocket
WSRobotPos();
//WSRobotInfo();
}
}
#region WebSocket数据接收
private ClientWebSocket ws_robot_pos;
///
/// 【机器人位置状态信息】
///
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(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(_jobject["msg"].ToString());
RobotObject.RobotPosQueue.Enqueue(_robot_pos);
}
}
}
}
catch (Exception ex)
{
Debug.LogError(ex.ToString());
}
}
///
/// 【机器人信息】
///
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(result), new CancellationToken());
var str = Encoding.UTF8.GetString(result, 0, result.Length);
//处理数据
RobotInfo[] _robot_info = JsonConvert.DeserializeObject(str.ToString());
RobotInfosQueue.Enqueue(_robot_info);
get_info_times++;
}
}
#endregion
#region 功能点2:下发巡检任务
/*
* 任务描述:
* 功能:点击机柜,下发巡检任务。
* 1.【获取机器人任务队列】先看机器人是否正在巡检(没有才下发)
* 2.【定点任务下发】“pointList“参数中”pointNo “为机柜巡检点,其他参数照抄不动
* 3.下发后看【获取机器人任务队列】是否巡检完成
* 4.巡检完成查看【查询巡检报表数据】将“pic“字段的值从” thermal “开始拆分,把thermal后的截取出来,发送到后台进行保存。
*/
///
/// 功能点2调用示例
///
/// 点位编号
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> _pics = new Dictionary>();
for (int i = 0; i < InsReport.thermal.Count; i++)
{
var _ps = new List();
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("图片路径处理完成!");
});
}));
});
});
}
///
/// 获取机器人任务列队
///
/// 参数1:异常信息;参数2:true->当前未在巡检
public void GetTaskQueue(Action _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(_data);
if (_response.rtCode.Equals(rtCode) && _response.rtData is JObject _jobject)
{
Debug.Log(_response.rtMsg);
if (_jobject != null)
{
RobotTask = _jobject.ToObject();
//实例化实体机器人的任务数据,注意机器人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);
}
}));
}
///
/// 机器人任务下发
///
public void PostRobotTask(string _point_no, Action _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(_data);
Debug.Log(_response.rtMsg);
if (_response.rtCode.Equals(rtCode))//返回值匹配表示下发成功
{
//下发成功后循环执行获取机器人任务队列,直至任务队列为空后继续执行后续操作
_callback?.Invoke(null, true);
}
else
{
_callback?.Invoke(_response.rtMsg, false);
}
}));
}
///
/// 执行循环查询等待操作
///
///
public IEnumerator Cyclic_GetTaskQuery(Action _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;
}
///
/// 获取巡检报表数据
///
public void GetInsReport(Action _callback)
{
//需补充请求参数,机器人任务队列中的Ins_Id,根据业务筛选具体数据
StartCoroutine(GetRequest(http_ip_address + get_record_ins_report, request_header, new Dictionary() { { "insId", RobotTask.data[0].Ins_Id } }, (_error, _data) =>
{
if (_error != null)
{
Debug.Log(_error);
_callback?.Invoke(_error, false);
return;
}
var _response = JsonConvert.DeserializeObject(_data);
if (_response.rtCode.Equals(rtCode) && _response.rtData is JObject _jobject)
{
Debug.Log(_response.rtMsg);
if (_jobject != null)
{
InsReport = _jobject.ToObject();
_callback?.Invoke(null, true);
}
}
else
{
_callback?.Invoke(_response.rtMsg, false);
}
}));
}
#endregion
#region 功能点3:巡检结果查看
public void ViewInspectionResults(Action> _callback)
{
//注意补充Token值
StartCoroutine(GetRequest(http_ip_ma_address + get_inspection, new Dictionary() { { "X-Token", "" } }, null, (_error, _data) =>
{
if (_error != null)
{
Debug.Log(_error);
_callback?.Invoke(_error, null);
return;
}
ResponseData_ma response = JsonConvert.DeserializeObject(_data);
if (response.message.Equals("操作成功") && response.data is JObject jobject)
{
if (response.data != null)
{
var inspection_datas = jobject.ToObject>();
var sprites = new List();
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();
}
///
/// 关闭ClientWebSocket。
///
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();
}
}
}