1.前后端增加复位功能
2.tcpclient心跳设置 3.优化后端启动速度 4.增加后端出库日志
This commit is contained in:
@ -9,531 +9,43 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using WCS.Model;
|
||||
using WCS.Model.ApiModel.Home;
|
||||
using 货架标准上位机.Api;
|
||||
|
||||
namespace 货架标准上位机.ViewModel
|
||||
{
|
||||
public class DeviceViewModel : BindableBase
|
||||
{
|
||||
//循环间隙时间
|
||||
int whileSleep = 1500;
|
||||
public ICommand ResetAllShelfCommand { get => new DelegateCommand(ResetAllShelf); }
|
||||
/// <summary>
|
||||
/// 是否繁忙。繁忙状态下不在进行定时刷新操作。
|
||||
/// 打开用户
|
||||
/// </summary>
|
||||
public bool IsBusy { get; set; } = false;
|
||||
//public IIoTBase plc;
|
||||
|
||||
#region 属性
|
||||
/// <summary>
|
||||
/// 监听
|
||||
/// </summary>
|
||||
public IEnumerable<DeviceReadModel> DataReads { get; set; }
|
||||
/// <summary>
|
||||
/// 控制
|
||||
/// </summary>
|
||||
public IEnumerable<DeviceWriteModel> DataWrites { get; set; }
|
||||
/// <summary>
|
||||
/// 气缸
|
||||
/// </summary>
|
||||
public IEnumerable<DeviceUrnModel> DataUrns { get; set; }
|
||||
/// <summary>
|
||||
/// 伺服
|
||||
/// </summary>
|
||||
public IEnumerable<DeviceServoModel> DataServos { get; set; }
|
||||
|
||||
private bool IsVis_ = false;
|
||||
/// <summary>
|
||||
/// 当前页面是否显示
|
||||
/// </summary>
|
||||
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
|
||||
|
||||
/// <summary>
|
||||
/// 循环读取数据
|
||||
/// </summary>
|
||||
public async void WhileRead()
|
||||
public void ResetAllShelf()
|
||||
{
|
||||
while (true)
|
||||
#region 调用接口 请求重置所有货架的状态
|
||||
var body = new ResetShelfStatusRequest()
|
||||
{
|
||||
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<bool>(plcAdd.地址);
|
||||
//item.Value = datab?.IsSucceed == true ? datab.Value : false;
|
||||
break;
|
||||
case "byte":
|
||||
//var datay = plc?.Read<byte>(plcAdd.地址);
|
||||
//item.Value = datay?.IsSucceed == true ? datay.Value : "-";
|
||||
break;
|
||||
case "int16":
|
||||
//var datai16 = plc?.Read<Int16>(plcAdd.地址);
|
||||
//item.Value = datai16?.IsSucceed == true ? datai16.Value : "-";
|
||||
break;
|
||||
case "int32":
|
||||
//var datai32 = plc?.Read<int>(plcAdd.地址);
|
||||
//item.Value = datai32?.IsSucceed == true ? datai32.Value : "-";
|
||||
break;
|
||||
case "uint16":
|
||||
//var dataui16 = plc?.Read<UInt16>(plcAdd.地址);
|
||||
//item.Value = dataui16?.IsSucceed == true ? dataui16.Value : "-";
|
||||
break;
|
||||
case "uint32":
|
||||
//var dataui32 = plc?.Read<UInt32>(plcAdd.地址);
|
||||
//item.Value = dataui32?.IsSucceed == true ? dataui32.Value : "-";
|
||||
break;
|
||||
case "float":
|
||||
case "single":
|
||||
//var datas = plc?.Read<float>(plcAdd.地址);
|
||||
//item.Value = datas?.IsSucceed == true ? datas.Value : "-";
|
||||
break;
|
||||
case "double":
|
||||
//var datad = plc?.Read<double>(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<bool>(plcAdd.读地址);
|
||||
//item.Value = datab?.IsSucceed == true ? datab.Value : false;
|
||||
break;
|
||||
case "byte":
|
||||
//var datay = plc?.Read<byte>(plcAdd.读地址);
|
||||
//item.Value = datay?.IsSucceed == true ? datay.Value : "-";
|
||||
break;
|
||||
case "int16":
|
||||
//var datai16 = plc?.Read<Int16>(plcAdd.读地址);
|
||||
//item.Value = datai16?.IsSucceed == true ? datai16.Value : "-";
|
||||
break;
|
||||
case "int32":
|
||||
//var datai32 = plc?.Read<int>(plcAdd.读地址);
|
||||
//item.Value = datai32?.IsSucceed == true ? datai32.Value : "-";
|
||||
break;
|
||||
case "uint16":
|
||||
//var dataui16 = plc?.Read<UInt16>(plcAdd.读地址);
|
||||
//item.Value = dataui16?.IsSucceed == true ? dataui16.Value : "-";
|
||||
break;
|
||||
case "uint32":
|
||||
//var dataui32 = plc?.Read<UInt32>(plcAdd.读地址);
|
||||
//item.Value = dataui32?.IsSucceed == true ? dataui32.Value : "-";
|
||||
break;
|
||||
case "float":
|
||||
case "single":
|
||||
//var datas = plc?.Read<float>(plcAdd.读地址);
|
||||
//item.Value = datas?.IsSucceed == true ? datas.Value : "-";
|
||||
break;
|
||||
case "double":
|
||||
//var datad = plc?.Read<double>(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<bool>(plcAdd.推到位地址);
|
||||
//item.IsGoTo = data1?.IsSucceed == true ? data1.Value : false;
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(plcAdd.回到位地址))
|
||||
{
|
||||
//var data2 = plc?.Read<bool>(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<float>(plcAdd.当前位置获取);
|
||||
//item.Location = data1?.IsSucceed == true ? data1.Value : 0;
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(plcAdd.手动速度获取) && (item.IsJog || !item.IsFold))
|
||||
{
|
||||
//var data2 = plc?.Read<Int16>(plcAdd.手动速度获取);
|
||||
//item.JogSpeed = data2?.IsSucceed == true ? data2.Value : 0;
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(plcAdd.自动速度设置) && (!item.IsJog || !item.IsFold))
|
||||
{
|
||||
//var data3 = plc?.Read<Int16>(plcAdd.自动速度设置);
|
||||
//item.AutoSpeed = data3?.IsSucceed == true ? data3.Value : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await Task.Delay(whileSleep);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
}
|
||||
IsResetAll = true,
|
||||
GroupNames = LocalFile.Config.GroupName,
|
||||
UserName = LocalStatic.CurrentUser,
|
||||
DeviceType = LocalFile.Config.DeviceType,
|
||||
};
|
||||
var Result = ApiHelp.GetDataFromHttp<ResponseBase>(LocalFile.Config.ApiIpHost + "home/resetShelfStatus", body, "POST");
|
||||
if (Result != null && Result.Code == 200)
|
||||
{
|
||||
Growl.Warning("复位成功!");
|
||||
}
|
||||
}
|
||||
|
||||
/*一起选中【操作控制】【操作气缸】【操作伺服】可以快速解开全部注释*/
|
||||
|
||||
#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("切换"))
|
||||
else if (Result != null)
|
||||
{
|
||||
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 });
|
||||
});
|
||||
Growl.Warning(Result.Message);
|
||||
}
|
||||
else
|
||||
{
|
||||
var ts = dataExcel.类型.Trim().ToLower();
|
||||
switch (ts)
|
||||
{
|
||||
case "byte":
|
||||
WriteClickDialog<byte>(data);
|
||||
break;
|
||||
case "int16":
|
||||
WriteClickDialog<Int16>(data);
|
||||
break;
|
||||
case "int32":
|
||||
WriteClickDialog<Int32>(data);
|
||||
break;
|
||||
case "uint16":
|
||||
WriteClickDialog<UInt16>(data);
|
||||
break;
|
||||
case "uint32":
|
||||
WriteClickDialog<UInt32>(data);
|
||||
break;
|
||||
case "float":
|
||||
case "single":
|
||||
WriteClickDialog<float>(data);
|
||||
break;
|
||||
case "double":
|
||||
WriteClickDialog<double>(data);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
Growl.Warning("调用接口失败!");
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
////单击弹框
|
||||
void WriteClickDialog<T>(DeviceWriteModel data) where T : struct
|
||||
{
|
||||
var dataExcel = data.ExcelTag;
|
||||
var val = TipInputView.Show<T>($"请输入新的[{dataExcel.名称}]值:", "修改值", "请输入值");
|
||||
if (!val.HasValue)
|
||||
return;
|
||||
|
||||
//plc?.Write<T>(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
|
||||
|
Reference in New Issue
Block a user