using AmrControl.ADS; using AmrControl.Clients; using AmrControl.Common.HttpClients; using AmrControl.Vo; using Microsoft.AspNetCore.SignalR.Protocol; using MQTTnet.Internal; using Newtonsoft.Json; using NPOI.SS.Formula.Functions; using System.Threading; namespace AmrControl.workstation { public class MsWorkstation { DateTime StartTime { get; set; } bool IsStart = false; int period = 0; /// /// 配置信息 /// private readonly IConfiguration _configuration; /// /// 服务获取 /// private readonly IServiceProvider _service; WsState wsState { get; set; } /// /// 锁对象 /// Mutex mutex = new Mutex(); public MsWorkstation(IConfiguration configuration, IServiceProvider service) { period = 1000; try { period = Int32.Parse(configuration["Mqtt:period"]); if(period < 500) { period = 500; } } catch { } StartTime = DateTime.Now; this._configuration = configuration; this._service = service; wsState = new WsState(); } TcClient client = null; //避免界面多次点击start方法 int reqCount = 0; public void Start() { reqCount++; if (reqCount > 1) return; Stop(); //if(client != null) //{ // client.Close(); //} //等待run退出,然后重启,有点风险 Thread.Sleep(period + period + period); //关闭ADS //client = TcClient.GetInstance(); //{ // client.Close(); //} StartTime = DateTime.Now; IsStart = true; Task.Run(run); reqCount = 0; } public void Stop() { IsStart = false; if (client != null) { client.Close(); } } bool isRuning = false; void run() { while(IsStart) { //更新ADS的IO状态 //Task.Run(readAds); //更新螺丝枪的状态 Task.Run(readElectricScrewdriver); //更新电烙铁的状态 Task.Run(readElectricIron); //if (client != null) //{ // Task.Run(watchStationState); //} //等待时间 Thread.Sleep(period); wsState.power = null; wsState.smokePurifier = null; wsState.balanceArm = null; wsState.triCokourLight = null; wsState.wristStrap = null; wsState.bodySensor = null; //发消息 string msg = Newtonsoft.Json.JsonConvert.SerializeObject(wsState); sendMqMessage(msg); } } void watchStationState() { try { if (client.State == false) client.InitAds(); //字节数,一个工位36个字节(倍福采用字节对齐方式最长4个字节)共18个工位的数据 byte[] datas = client.ReadBytes("GVL_STATION.Station_Var", 648); List stationList = new(); int stationPos = 1; for (var i = 0; i < datas.Length; i += 36) { stationList.Add(new() { stationPosNo = (stationPos++), //此处按规则新增工站编号信息(位置从仓储开始计算工位) power = Convert.ToBoolean(datas[i] | (datas[i + 1] << 8) | (datas[i + 2] << 16) | (datas[i + 3] << 32)), triColorLight = Convert.ToInt16(datas[i + 4] | (datas[i + 5] << 8) | (datas[i + 6] << 16) | (datas[i + 7] << 32)), wsristStrapMonitorCh1 = Convert.ToInt16(datas[i + 8] | (datas[i + 9] << 8) | (datas[i + 10] << 16) | (datas[i + 11] << 32)), wsristStrapMonitorCh2 = Convert.ToInt16(datas[i + 12] | (datas[i + 13] << 8) | (datas[i + 14] << 16) | (datas[i + 15] << 32)), smokePurifier = Convert.ToBoolean(datas[i + 16] | (datas[i + 17] << 8) | (datas[i + 18] << 16) | (datas[i + 19] << 32)), bigArm_encoding = Convert.ToInt16(datas[i + 20] | (datas[i + 21] << 8) | (datas[i + 22] << 16) | (datas[i + 23] << 32)), bigArm_angle = Convert.ToSingle(datas[i + 24] | (datas[i + 25] << 8) | (datas[i + 26] << 16) | (datas[i + 27] << 32)), smallArm_encoding = Convert.ToInt16(datas[i + 28] | (datas[i + 29] << 8) | (datas[i + 30] << 16) | (datas[i + 31] << 32)), smallArm_angle = Convert.ToSingle(datas[i + 32] | (datas[i + 29] << 33) | (datas[i + 34] << 16) | (datas[i + 35] << 32)), }); } Console.WriteLine("stationStatus=======>"+JsonConvert.SerializeObject(stationList)); Console.WriteLine("current station:" + JsonConvert.SerializeObject(stationList[8])); //将结果推送到前端,后期可修改为使用mq推送 this.wsState.triCokourLight = stationList[8].triColorLight == 0 ? "off" : (stationList[8].triColorLight == 1 ? "green" : (stationList[8].triColorLight == 2 ? "yellow" : "red")); this.wsState.wristStrap = stationList[8].wsristStrapMonitorCh1 == 0 && stationList[8].wsristStrapMonitorCh2 == 0 ? "off" : (stationList[8].wsristStrapMonitorCh1 == 1 && stationList[8].wsristStrapMonitorCh2 == 1 ? "uwear" : "wear"); this.wsState.smokePurifier = stationList[8].smokePurifier ? "on" : "off"; this.wsState.power.state = stationList[8].power ? "on" : "off"; } catch (Exception ex) { Console.WriteLine(ex.ToString()); } } //ADS读 void readAds() { //TcClient client = TcClient.GetInstance(); //if (client == null) // return; //if (client.State == false) // client.InitAds(); //读参数 } //螺丝枪更新,从http的get请求获取 void readElectricScrewdriver() { try { //todo::,从网络获取数据 //http://10.10.25.100:8081/api/v1.0/processdata/latestfinalvalueobject DefaultHttpClient http = DefaultHttpClient.getClient("http://192.168.148.253:8081"); Dictionary header = new Dictionary(); header["Authorization"] = "Basic YWRtaW46MDAwMA=="; HttpRespResult result = http.httpGetClient().sendRequest("/api/v1.0/processdata/latestfinalvalueobject", header, null); if(result == null || result.data == null) { return; } DeprageElecScrewdriver deprage = Newtonsoft.Json.JsonConvert.DeserializeObject(result.data); if(deprage != null && deprage.Steps != null && deprage.Steps.Count > 0) { //在线 this.wsState.electricScrewdriver.state = "on"; StepState? state = deprage.Steps.Where(step => step.StepNumber==1).FirstOrDefault(); if(state != null) { this.wsState.electricScrewdriver.angle = state.Angle.Value.ToString("0.00"); this.wsState.electricScrewdriver.torqueForce = state.Torque.Value.ToString("0.0"); this.wsState.electricScrewdriver.lowTorqueForce = state.Torque.Target.Lower.ToString("0.0"); this.wsState.electricScrewdriver.highTorqueForce = state.Torque.Target.Upper.ToString("0.0"); } else { this.wsState.electricScrewdriver.angle = "0.00"; this.wsState.electricScrewdriver.torqueForce = "0.0"; this.wsState.electricScrewdriver.lowTorqueForce = "0.0"; this.wsState.electricScrewdriver.highTorqueForce = "0.0"; } } else { //不在线 this.wsState.electricScrewdriver.state = "off"; } } catch { } } bool electricIronInit = false; int units = 0; //电烙铁更新 void readElectricIron() { try { if (!electricIronInit) { mutex.WaitOne(); try { if (!electricIronInit) { units = JbcDllInvoke.Init(); Console.WriteLine($"read init result. {units}"); electricIronInit = true; } } finally { mutex.ReleaseMutex(); } } if (electricIronInit && units > 0) { try { Console.WriteLine($"初始化jbc,值为:{units}"); int status = JbcDllInvoke.GetPortToolSleepStatus(units); Console.WriteLine($"read sleep status:{status}"); this.wsState.electricIron.state = status > 0 ? "off" : "on"; //获取设定值 int setTemp = JbcDllInvoke.GetPortToolSelectedTemp(units, 1); Console.WriteLine($"set temperature:{setTemp}"); this.wsState.electricIron.setTemperature = setTemp.ToString(); int temp = JbcDllInvoke.GetPortToolActualTemp(units, 1); Console.WriteLine($"actual temperature:{temp}"); this.wsState.electricIron.temperature = temp.ToString(); int maxTemp = JbcDllInvoke.GetStationMaxTemp(units); Console.WriteLine($"max temperature:{maxTemp}"); this.wsState.electricIron.highTemp = maxTemp.ToString(); int minTemp = JbcDllInvoke.GetStationMinTemp(units); Console.WriteLine($"min temperature:{minTemp}"); this.wsState.electricIron.lowTemp = minTemp.ToString(); this.wsState.electricIron.warning = temp > maxTemp && temp < minTemp ? "true" : "false"; } catch { electricIronInit = false; } } } catch (Exception ex) { Console.WriteLine (ex.Message ); } } /// /// 接收到MQ消息,是命令 /// /// /// public void PushMqMessage(string topic, string message) { if (string.IsNullOrEmpty(message)) return; try { WsCmd wscmd = (WsCmd)Newtonsoft.Json.JsonConvert.DeserializeObject(message); if (wscmd != null && wscmd.Cmd=="start") { if (wscmd.Cmd == "start") { Start(); } else if (wscmd.Cmd == "stop") { Stop(); } } } catch(Exception ex) { } } void sendMqMessage(string msg) { try { MqttClient _mqttClient = _service.GetRequiredService(); if (_mqttClient != null) { _mqttClient.SendToMqtt(msg); } } catch { } } } public interface IWorkstation { void Start(); void Stop(); void PushMqMessage(string topic , string message); } }