using HandyControl.Controls; using Ping9719.WpfEx; using Ping9719.WpfEx.Mvvm; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Input; namespace 货架标准上位机.ViewModel { public class DeviceViewModel : BindableBase { //循环间隙时间 int whileSleep = 1500; /// /// 是否繁忙。繁忙状态下不在进行定时刷新操作。 /// public bool IsBusy { get; set; } = false; //public IIoTBase plc; #region 属性 /// /// 监听 /// public IEnumerable DataReads { get; set; } /// /// 控制 /// public IEnumerable DataWrites { get; set; } /// /// 气缸 /// public IEnumerable DataUrns { get; set; } /// /// 伺服 /// public IEnumerable DataServos { get; set; } private bool IsVis_ = false; /// /// 当前页面是否显示 /// public bool IsVis { get => IsVis_; set { SetProperty(ref IsVis_, value); } } #region 是否展示 private bool IsVisRead_ = true; public bool IsVisRead { get => IsVisRead_; set { SetProperty(ref IsVisRead_, value); } } private bool IsVisWrite_ = true; public bool IsVisWrite { get => IsVisWrite_; set { SetProperty(ref IsVisWrite_, value); } } private bool IsVisUrn_ = true; public bool IsVisUrn { get => IsVisUrn_; set { SetProperty(ref IsVisUrn_, value); } } private bool IsVisServo_ = true; public bool IsVisServo { get => IsVisServo_; set { SetProperty(ref IsVisServo_, value); } } #endregion #region 是否折叠 private bool IsVisExpRead_ = true; public bool IsVisExpRead { get => IsVisExpRead_; set { SetProperty(ref IsVisExpRead_, value); } } private bool IsVisExpWrite_ = true; public bool IsVisExpWrite { get => IsVisExpWrite_; set { SetProperty(ref IsVisExpWrite_, value); } } private bool IsVisExpUrn_ = false; public bool IsVisExpUrn { get => IsVisExpUrn_; set { SetProperty(ref IsVisExpUrn_, value); } } private bool IsVisExpServo_ = false; public bool IsVisExpServo { get => IsVisExpServo_; set { SetProperty(ref IsVisExpServo_, value); } } #endregion #endregion /// /// 循环读取数据 /// public async void WhileRead() { while (true) { try { if (!IsVis || IsBusy) { await Task.Delay(whileSleep); continue; } ////监控 if (DataReads != null && IsVisExpRead) { foreach (var item in DataReads) { if (!item.IsExpanded) continue; var plcAdd = item.ExcelTag; if (string.IsNullOrWhiteSpace(plcAdd.地址)) continue; var ts = plcAdd.类型.Trim().ToLower(); switch (ts) { case "bool": //var datab = plc?.Read(plcAdd.地址); //item.Value = datab?.IsSucceed == true ? datab.Value : false; break; case "byte": //var datay = plc?.Read(plcAdd.地址); //item.Value = datay?.IsSucceed == true ? datay.Value : "-"; break; case "int16": //var datai16 = plc?.Read(plcAdd.地址); //item.Value = datai16?.IsSucceed == true ? datai16.Value : "-"; break; case "int32": //var datai32 = plc?.Read(plcAdd.地址); //item.Value = datai32?.IsSucceed == true ? datai32.Value : "-"; break; case "uint16": //var dataui16 = plc?.Read(plcAdd.地址); //item.Value = dataui16?.IsSucceed == true ? dataui16.Value : "-"; break; case "uint32": //var dataui32 = plc?.Read(plcAdd.地址); //item.Value = dataui32?.IsSucceed == true ? dataui32.Value : "-"; break; case "float": case "single": //var datas = plc?.Read(plcAdd.地址); //item.Value = datas?.IsSucceed == true ? datas.Value : "-"; break; case "double": //var datad = plc?.Read(plcAdd.地址); //item.Value = datad?.IsSucceed == true ? datad.Value : "-"; break; default: break; } } } ////控制 if (DataWrites != null && IsVisExpWrite) { foreach (var item in DataWrites) { if (!item.IsExpanded) continue; var plcAdd = item.ExcelTag; if (string.IsNullOrWhiteSpace(plcAdd.读地址)) continue; var ts = plcAdd.类型.Trim().ToLower(); switch (ts) { case "bool": //var datab = plc?.Read(plcAdd.读地址); //item.Value = datab?.IsSucceed == true ? datab.Value : false; break; case "byte": //var datay = plc?.Read(plcAdd.读地址); //item.Value = datay?.IsSucceed == true ? datay.Value : "-"; break; case "int16": //var datai16 = plc?.Read(plcAdd.读地址); //item.Value = datai16?.IsSucceed == true ? datai16.Value : "-"; break; case "int32": //var datai32 = plc?.Read(plcAdd.读地址); //item.Value = datai32?.IsSucceed == true ? datai32.Value : "-"; break; case "uint16": //var dataui16 = plc?.Read(plcAdd.读地址); //item.Value = dataui16?.IsSucceed == true ? dataui16.Value : "-"; break; case "uint32": //var dataui32 = plc?.Read(plcAdd.读地址); //item.Value = dataui32?.IsSucceed == true ? dataui32.Value : "-"; break; case "float": case "single": //var datas = plc?.Read(plcAdd.读地址); //item.Value = datas?.IsSucceed == true ? datas.Value : "-"; break; case "double": //var datad = plc?.Read(plcAdd.读地址); //item.Value = datad?.IsSucceed == true ? datad.Value : "-"; break; default: break; } } } ////气缸 if (DataUrns != null && IsVisExpUrn) { foreach (var item in DataUrns) { if (!item.IsExpanded) continue; var plcAdd = item.ExcelTag; if (!string.IsNullOrWhiteSpace(plcAdd.推到位地址)) { //var data1 = plc?.Read(plcAdd.推到位地址); //item.IsGoTo = data1?.IsSucceed == true ? data1.Value : false; } if (!string.IsNullOrWhiteSpace(plcAdd.回到位地址)) { //var data2 = plc?.Read(plcAdd.回到位地址); //item.IsRetTo = data2?.IsSucceed == true ? data2.Value : false; } } } ////伺服 if (DataServos != null && IsVisExpServo) { foreach (var item in DataServos) { if (!item.IsExpanded) continue; ////读取地址信息 var plcAdd = item.ExcelTag; if (!string.IsNullOrWhiteSpace(plcAdd.当前位置获取)) { //var data1 = plc?.Read(plcAdd.当前位置获取); //item.Location = data1?.IsSucceed == true ? data1.Value : 0; } if (!string.IsNullOrWhiteSpace(plcAdd.手动速度获取) && (item.IsJog || !item.IsFold)) { //var data2 = plc?.Read(plcAdd.手动速度获取); //item.JogSpeed = data2?.IsSucceed == true ? data2.Value : 0; } if (!string.IsNullOrWhiteSpace(plcAdd.自动速度设置) && (!item.IsJog || !item.IsFold)) { //var data3 = plc?.Read(plcAdd.自动速度设置); //item.AutoSpeed = data3?.IsSucceed == true ? data3.Value : 0; } } } await Task.Delay(whileSleep); } catch (Exception) { } } } /*一起选中【操作控制】【操作气缸】【操作伺服】可以快速解开全部注释*/ #region 操作控制 ////单击 public void WriteClick(object sender, RoutedEventArgs e) { var data = (DeviceWriteModel)((FrameworkElement)sender).DataContext; var dataExcel = data.ExcelTag; var mode = dataExcel.点动切换?.Trim() ?? ""; if (dataExcel.类型.Trim().ToLower() == "bool" && mode.StartsWith("切换")) { Task.Run(() => { var boolval = data.Value is true; //plc?.Write(dataExcel.写地址, !boolval); data.Value = !boolval; IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "控制", Funct = string.Empty, Val = data.Value, Mode = mode }); }); } else { var ts = dataExcel.类型.Trim().ToLower(); switch (ts) { case "byte": WriteClickDialog(data); break; case "int16": WriteClickDialog(data); break; case "int32": WriteClickDialog(data); break; case "uint16": WriteClickDialog(data); break; case "uint32": WriteClickDialog(data); break; case "float": case "single": WriteClickDialog(data); break; case "double": WriteClickDialog(data); break; default: break; } } } ////单击弹框 void WriteClickDialog(DeviceWriteModel data) where T : struct { var dataExcel = data.ExcelTag; var val = TipInputView.Show($"请输入新的[{dataExcel.名称}]值:", "修改值", "请输入值"); if (!val.HasValue) return; //plc?.Write(dataExcel.写地址, val.Value); IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "控制", Funct = string.Empty, Val = val.Value, Mode = "" }); } ////按下左键 public void LeftDown(object sender, MouseButtonEventArgs e) { var data = (DeviceWriteModel)((FrameworkElement)sender).DataContext; var dataExcel = data.ExcelTag; var mode = dataExcel.点动切换?.Trim() ?? ""; if (dataExcel.类型.Trim().ToLower() == "bool" && mode.StartsWith("点动")) { Task.Run(() => { //plc?.Write(dataExcel.写地址, true); data.Value = true; IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "控制", Funct = string.Empty, Val = data.Value, Mode = mode }); }); } } ////放开左键 public void LeftUp(object sender, MouseButtonEventArgs e) { var data = (DeviceWriteModel)((FrameworkElement)sender).DataContext; var dataExcel = data.ExcelTag; var mode = dataExcel.点动切换?.Trim() ?? ""; if (dataExcel.类型.Trim().ToLower() == "bool" && mode.StartsWith("点动")) { Task.Run(() => { //plc?.Write(dataExcel.写地址, false); data.Value = false; IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "控制", Funct = string.Empty, Val = data.Value, Mode = mode }); }); } } #endregion #region 操作气缸 ////按钮1单击 public void Button1_Click(object sender, RoutedEventArgs e) { var data = (DeviceUrnModel)((FrameworkElement)sender).DataContext; var dataExcel = data.ExcelTag; var mode = dataExcel.点动切换?.Trim() ?? ""; if (mode.StartsWith("切换")) { Task.Run(() => { //plc?.Write(dataExcel.推地址, true); //plc?.Write(dataExcel.回地址, false); IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "气缸", Funct = "推", Val = true, Mode = mode }); }); } } ////按钮1按下 public void But1ClickDown(object sender, RoutedEventArgs e) { var data = (DeviceUrnModel)((FrameworkElement)sender).DataContext; var dataExcel = data.ExcelTag; var mode = dataExcel.点动切换?.Trim() ?? ""; if (mode.StartsWith("点动")) { Task.Run(() => { //plc?.Write(dataExcel.推地址, true); data.IsGoTo = true; IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "气缸", Funct = "推", Val = true, Mode = mode }); }); } } ////按钮1松开 public void But1ClickUp(object sender, RoutedEventArgs e) { var data = (DeviceUrnModel)((FrameworkElement)sender).DataContext; var dataExcel = data.ExcelTag; var mode = dataExcel.点动切换?.Trim() ?? ""; if (mode.StartsWith("点动")) { Task.Run(() => { //plc?.Write(dataExcel.推地址, false); data.IsGoTo = false; IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "气缸", Funct = "推", Val = false, Mode = mode }); }); } } ////按钮2单击 public void Button2_Click(object sender, RoutedEventArgs e) { var data = (DeviceUrnModel)((FrameworkElement)sender).DataContext; var dataExcel = data.ExcelTag; var mode = dataExcel.点动切换?.Trim() ?? ""; if (mode.StartsWith("切换")) { Task.Run(() => { //plc?.Write(dataExcel.推地址, false); //plc?.Write(dataExcel.回地址, true); IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "气缸", Funct = "回", Val = true, Mode = mode }); }); } } ////按钮2按下 public void But2ClickDown(object sender, RoutedEventArgs e) { var data = (DeviceUrnModel)((FrameworkElement)sender).DataContext; var dataExcel = data.ExcelTag; var mode = dataExcel.点动切换?.Trim() ?? ""; if (mode.StartsWith("点动")) { Task.Run(() => { //plc?.Write(dataExcel.回地址, true); data.IsRetTo = true; IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "气缸", Funct = "回", Val = true, Mode = mode }); }); } } ////按钮2松开 public void But2ClickUp(object sender, RoutedEventArgs e) { var data = (DeviceUrnModel)((FrameworkElement)sender).DataContext; var dataExcel = data.ExcelTag; var mode = dataExcel.点动切换?.Trim() ?? ""; if (mode.StartsWith("点动")) { Task.Run(() => { //plc?.Write(dataExcel.回地址, false); data.IsRetTo = false; IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "气缸", Funct = "回", Val = false, Mode = mode }); }); } } #endregion #region 操作伺服 ////尝试改变伺服的位置时 public void LocationChange(object sender, RoutedEventArgs e) { var data = (DeviceServoModel)((FrameworkElement)sender).DataContext; var dataExcel = data.ExcelTag; var mode = string.Empty; ////运动方式 if (e.OriginalSource is ServoClickType servoClickType) { if (servoClickType == ServoClickType.StartDotAdd) { //plc?.Write(dataExcel.位置点动加, true); IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "伺服", Funct = "开始点动加", Val = true, Mode = mode }); } else if (servoClickType == ServoClickType.EndDotAdd) { //plc?.Write(dataExcel.位置点动加, false); IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "伺服", Funct = "结束点动加", Val = false, Mode = mode }); } else if (servoClickType == ServoClickType.StartDotSub) { //plc?.Write(dataExcel.位置点动减, true); IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "伺服", Funct = "开始点动减", Val = true, Mode = mode }); } else if (servoClickType == ServoClickType.EndDotSub) { //plc?.Write(dataExcel.位置点动减, false); IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "伺服", Funct = "结束点动减", Val = false, Mode = mode }); } } ////运动到指定位置 else if (e.OriginalSource is double val) { //plc?.Write(dataExcel.位置移动, Convert.ToSingle(val)); data.Location = val; IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "伺服", Funct = "位置移动", Val = val, Mode = mode }); } } ////尝试改变伺服的速度时 public void SpeedChange(object sender, RoutedEventArgs e) { var data = (DeviceServoModel)((FrameworkElement)sender).DataContext; var dataExcel = data.ExcelTag; var mode = string.Empty; var data2 = (ServoSpeed)e.OriginalSource; if (data2.Name.StartsWith("手动")) { //plc?.Write(dataExcel.手动速度设置, Convert.ToSingle(data2.Speed)); data.JogSpeed = data2.Speed; IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "伺服", Funct = "手动速度设置", Val = data2.Speed, Mode = mode }); } else { //plc?.Write(dataExcel.自动速度设置, Convert.ToSingle(data2.Speed)); data.AutoSpeed = data2.Speed; IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "伺服", Funct = "自动速度设置", Val = data2.Speed, Mode = mode }); } } #endregion } public class DeviceReadModel : BindableBase { #region 属性 private string Name_; /// /// 名称 /// public string Name { get => Name_; set { SetProperty(ref Name_, value); } } private object Value_; /// /// 值 /// public object Value { get => Value_; set { SetProperty(ref Value_, value); } } /// /// 是否可见 /// public bool IsExpanded { get; set; } /// /// Excel原始数据 /// public ExcelDeviceReadModel ExcelTag { get; set; } #endregion } public class DeviceWriteModel : BindableBase { #region 属性 private string Name_; /// /// 名称 /// public string Name { get => Name_; set { SetProperty(ref Name_, value); } } private object Value_; /// /// 是否合格 /// public object Value { get => Value_; set { SetProperty(ref Value_, value); } } /// /// 是否可见 /// public bool IsExpanded { get; set; } /// /// Excel原始数据 /// public ExcelDeviceWriteModel ExcelTag { get; set; } #endregion } public class DeviceUrnModel : BindableBase { #region 属性 private string Name_; /// /// 名称 /// public string Name { get => Name_; set { SetProperty(ref Name_, value); } } private bool IsGoTo_; /// /// 是否推到位 /// public bool IsGoTo { get => IsGoTo_; set { SetProperty(ref IsGoTo_, value); } } private bool IsRetTo_; /// /// 是否回到位 /// public bool IsRetTo { get => IsRetTo_; set { SetProperty(ref IsRetTo_, value); } } /// /// 是否可见 /// public bool IsExpanded { get; set; } /// /// 自定义数据 /// public ExcelDeviceUrnModel ExcelTag { get; set; } #endregion } public class DeviceServoModel : BindableBase { #region 属性 private string Name_; /// /// 名称 /// public string Name { get => Name_; set { SetProperty(ref Name_, value); } } private double JogSpeed_; /// /// 手动模式速度 /// public double JogSpeed { get => JogSpeed_; set { SetProperty(ref JogSpeed_, value); } } private double AutoSpeed_; /// /// 自动模式速度 /// public double AutoSpeed { get => AutoSpeed_; set { SetProperty(ref AutoSpeed_, value); } } private double Location_; /// /// 伺服当前位置 /// public double Location { get => Location_; set { SetProperty(ref Location_, value); } } private bool IsJog_ = true; /// /// 是否主页显示为手动模式 /// public bool IsJog { get => IsJog_; set { SetProperty(ref IsJog_, value); } } private bool IsFold_ = true; /// /// 是否折叠 /// public bool IsFold { get => IsFold_; set { SetProperty(ref IsFold_, value); } } /// /// 是否可见 /// public bool IsExpanded { get; set; } private ExcelDeviceServoModel ExcelTag_; /// /// 自定义数据 /// public ExcelDeviceServoModel ExcelTag { get => ExcelTag_; set { SetProperty(ref ExcelTag_, value); } } #endregion } }