|
@@ -1,8 +1,10 @@
|
|
using CommunityToolkit.Mvvm.ComponentModel;
|
|
using CommunityToolkit.Mvvm.ComponentModel;
|
|
using CommunityToolkit.Mvvm.Input;
|
|
using CommunityToolkit.Mvvm.Input;
|
|
|
|
+using GeneralData;
|
|
using Mini8SlaveSim.Configuration;
|
|
using Mini8SlaveSim.Configuration;
|
|
using Mini8SlaveSim.Services;
|
|
using Mini8SlaveSim.Services;
|
|
using System.Collections.ObjectModel;
|
|
using System.Collections.ObjectModel;
|
|
|
|
+using System.Windows.Controls;
|
|
using System.Windows.Threading;
|
|
using System.Windows.Threading;
|
|
|
|
|
|
namespace Mini8SlaveSim.ViewModels;
|
|
namespace Mini8SlaveSim.ViewModels;
|
|
@@ -12,11 +14,11 @@ public partial class RowItem : ObservableObject
|
|
[ObservableProperty]
|
|
[ObservableProperty]
|
|
private string _name = string.Empty;
|
|
private string _name = string.Empty;
|
|
[ObservableProperty]
|
|
[ObservableProperty]
|
|
- private string _ch1 = string.Empty;
|
|
|
|
|
|
+ private string _ch1 = string.Empty;
|
|
[ObservableProperty]
|
|
[ObservableProperty]
|
|
- private string _ch2 = string.Empty;
|
|
|
|
|
|
+ private string _ch2 = string.Empty;
|
|
[ObservableProperty]
|
|
[ObservableProperty]
|
|
- private string _ch3 = string.Empty;
|
|
|
|
|
|
+ private string _ch3 = string.Empty;
|
|
[ObservableProperty]
|
|
[ObservableProperty]
|
|
private string _ch4 = string.Empty;
|
|
private string _ch4 = string.Empty;
|
|
[ObservableProperty]
|
|
[ObservableProperty]
|
|
@@ -48,8 +50,7 @@ public partial class RowItem : ObservableObject
|
|
enum DataType
|
|
enum DataType
|
|
{
|
|
{
|
|
UShort = 1,
|
|
UShort = 1,
|
|
- Float = 2,
|
|
|
|
- Double = 4
|
|
|
|
|
|
+ Float = 2
|
|
}
|
|
}
|
|
|
|
|
|
public partial class Mini8TabViewModel : ObservableObject
|
|
public partial class Mini8TabViewModel : ObservableObject
|
|
@@ -58,22 +59,22 @@ public partial class Mini8TabViewModel : ObservableObject
|
|
private readonly ISlaveManagementService _slaveManagementService;
|
|
private readonly ISlaveManagementService _slaveManagementService;
|
|
|
|
|
|
private readonly byte _slaveId = 0;
|
|
private readonly byte _slaveId = 0;
|
|
- private readonly Dictionary<string, Dictionary<byte,(ushort,DataType)>> _pointNamePosition = [];
|
|
|
|
|
|
+ private readonly Dictionary<string, Dictionary<byte, (ushort, DataType)>> _pointNamePosition = [];
|
|
private readonly DispatcherTimer _timer;
|
|
private readonly DispatcherTimer _timer;
|
|
|
|
|
|
[ObservableProperty]
|
|
[ObservableProperty]
|
|
private ObservableCollection<RowItem> _rowItems = [];
|
|
private ObservableCollection<RowItem> _rowItems = [];
|
|
|
|
|
|
[ObservableProperty]
|
|
[ObservableProperty]
|
|
- private string _registerName=string.Empty;
|
|
|
|
|
|
+ private string _registerName = string.Empty;
|
|
|
|
|
|
[ObservableProperty]
|
|
[ObservableProperty]
|
|
- private string _channelNumber=string.Empty;
|
|
|
|
|
|
+ private string _channelNumber = string.Empty;
|
|
|
|
|
|
[ObservableProperty]
|
|
[ObservableProperty]
|
|
- private string _writeValue= string.Empty;
|
|
|
|
|
|
+ private string _writeValue = string.Empty;
|
|
|
|
|
|
- public Mini8TabViewModel(ISharedConfig sharedConfig, ISlaveManagementService slaveManagementService)
|
|
|
|
|
|
+ public Mini8TabViewModel(ISharedConfig sharedConfig, ISlaveManagementService slaveManagementService)
|
|
{
|
|
{
|
|
_sharedConfig = sharedConfig;
|
|
_sharedConfig = sharedConfig;
|
|
_slaveManagementService = slaveManagementService;
|
|
_slaveManagementService = slaveManagementService;
|
|
@@ -85,6 +86,41 @@ public partial class Mini8TabViewModel : ObservableObject
|
|
}
|
|
}
|
|
|
|
|
|
[RelayCommand]
|
|
[RelayCommand]
|
|
|
|
+ private void CellClick(SelectedCellsChangedEventArgs e)
|
|
|
|
+ {
|
|
|
|
+ var added = e.AddedCells.FirstOrDefault();
|
|
|
|
+ if (added.Column is null || added.Item is null)
|
|
|
|
+ {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ var row = (RowItem)added.Item;
|
|
|
|
+
|
|
|
|
+ var header = added.Column.Header.ToString() ?? string.Empty;
|
|
|
|
+ if (string.IsNullOrWhiteSpace(header))
|
|
|
|
+ {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ string chStr = string.Empty;
|
|
|
|
+ for (int i = 0; i < header.Length; i++)
|
|
|
|
+ {
|
|
|
|
+ if (Char.IsDigit(header[i]))
|
|
|
|
+ {
|
|
|
|
+ chStr += header[i];
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (string.IsNullOrWhiteSpace(chStr))
|
|
|
|
+ {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ RegisterName = row.Name;
|
|
|
|
+ ChannelNumber = chStr;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ [RelayCommand]
|
|
private void Write()
|
|
private void Write()
|
|
{
|
|
{
|
|
if (!_pointNamePosition.TryGetValue(RegisterName, out var register) || register is null)
|
|
if (!_pointNamePosition.TryGetValue(RegisterName, out var register) || register is null)
|
|
@@ -101,26 +137,37 @@ public partial class Mini8TabViewModel : ObservableObject
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- var finalValueStr = WriteValue.Replace("0x", "");
|
|
|
|
- var registerNumber = (ushort)posDatatype.Item2;
|
|
|
|
- if(finalValueStr.Length!= registerNumber*4)
|
|
|
|
|
|
+ var slave = _slaveManagementService.Slaves[_slaveId];
|
|
|
|
+ var dataStore = slave.SlaveDataStore;
|
|
|
|
+
|
|
|
|
+ if (posDatatype.Item2 == DataType.UShort)
|
|
{
|
|
{
|
|
|
|
+ if (!ushort.TryParse(WriteValue, out var finalValue))
|
|
|
|
+ {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ slave.TryWriteValues(dataStore.HoldingRegisters, posDatatype.Item1, [finalValue]);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- ushort[] points=new ushort[registerNumber];
|
|
|
|
- for (int i = 0; i < registerNumber; i++)
|
|
|
|
|
|
+ if (posDatatype.Item2 == DataType.Float)
|
|
{
|
|
{
|
|
- if (!ushort.TryParse(finalValueStr.Substring(i * 4, 4), System.Globalization.NumberStyles.HexNumber, null, out var finalValue))
|
|
|
|
|
|
+ if (!float.TryParse(WriteValue, out var floatValue))
|
|
{
|
|
{
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
- points[i] = finalValue;
|
|
|
|
|
|
+
|
|
|
|
+ var bytes = BitConverter.GetBytes(floatValue);
|
|
|
|
+ if(BitConverter.IsLittleEndian)
|
|
|
|
+ {
|
|
|
|
+ Array.Reverse(bytes);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ var high = BitConverter.ToUInt16([bytes[1],bytes[0]], 0);
|
|
|
|
+ var low = BitConverter.ToUInt16([bytes[3], bytes[2]], 0);
|
|
|
|
+ slave.TryWriteValues(dataStore.HoldingRegisters, posDatatype.Item1, [high, low]);
|
|
}
|
|
}
|
|
-
|
|
|
|
- var slave = _slaveManagementService.Slaves[_slaveId];
|
|
|
|
- var dataStore = slave.SlaveDataStore;
|
|
|
|
- slave.TryWriteValues(dataStore.HoldingRegisters, posDatatype.Item1, points);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
private void OnTimeup(object? sender, EventArgs e)
|
|
private void OnTimeup(object? sender, EventArgs e)
|
|
@@ -136,80 +183,139 @@ public partial class Mini8TabViewModel : ObservableObject
|
|
var chNumber = ch.Key;
|
|
var chNumber = ch.Key;
|
|
var registerPos = ch.Value.Item1;
|
|
var registerPos = ch.Value.Item1;
|
|
var usedRegister = (ushort)ch.Value.Item2;
|
|
var usedRegister = (ushort)ch.Value.Item2;
|
|
|
|
+
|
|
var rst = slave.TryReadValues(dataStore.HoldingRegisters, registerPos, usedRegister, out var outPoints);
|
|
var rst = slave.TryReadValues(dataStore.HoldingRegisters, registerPos, usedRegister, out var outPoints);
|
|
if (!rst || outPoints is null)
|
|
if (!rst || outPoints is null)
|
|
{
|
|
{
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
- string valueStr = "0x";
|
|
|
|
- foreach(var item in outPoints)
|
|
|
|
|
|
+
|
|
|
|
+ string valueStr = string.Empty;
|
|
|
|
+ foreach (var item in outPoints)
|
|
{
|
|
{
|
|
- valueStr += $"{item:X4}";
|
|
|
|
|
|
+ var ushortStr = Convert.ToString(item, 2).PadLeft(16, '0');
|
|
|
|
+ valueStr += ushortStr;
|
|
}
|
|
}
|
|
- var rowitem = RowItems.First(item => item.Name == pointName);
|
|
|
|
- App.Current.Dispatcher.BeginInvoke(() =>
|
|
|
|
|
|
+
|
|
|
|
+ if (usedRegister == (int)DataType.UShort)
|
|
{
|
|
{
|
|
- switch (chNumber)
|
|
|
|
|
|
+ var value = Convert.ToUInt16(valueStr, 2);
|
|
|
|
+ if (pointName == "AutoTuneStatus")
|
|
|
|
+ {
|
|
|
|
+ valueStr = value switch
|
|
|
|
+ {
|
|
|
|
+ (ushort)AutoTuneStatus.Unavailable => AutoTuneStatus.Unavailable.ToString(),
|
|
|
|
+ (ushort)AutoTuneStatus.Ready => AutoTuneStatus.Ready.ToString(),
|
|
|
|
+ (ushort)AutoTuneStatus.Triggered => AutoTuneStatus.Triggered.ToString(),
|
|
|
|
+ (ushort)AutoTuneStatus.Tuning => AutoTuneStatus.Tuning.ToString(),
|
|
|
|
+ (ushort)AutoTuneStatus.Complete => AutoTuneStatus.Complete.ToString(),
|
|
|
|
+ (ushort)AutoTuneStatus.Aborted => AutoTuneStatus.Aborted.ToString(),
|
|
|
|
+ (ushort)AutoTuneStatus.Timeout => AutoTuneStatus.Timeout.ToString(),
|
|
|
|
+ (ushort)AutoTuneStatus.Overflow => AutoTuneStatus.Overflow.ToString(),
|
|
|
|
+ _ => throw new NotImplementedException(),
|
|
|
|
+ };
|
|
|
|
+ }
|
|
|
|
+ else if (pointName == "SensorBreakAlarm1" || pointName == "SensorBreakAlarm2")
|
|
{
|
|
{
|
|
- case 1:
|
|
|
|
- if (rowitem.Ch1 != valueStr) rowitem.Ch1 = valueStr;
|
|
|
|
- break;
|
|
|
|
- case 2:
|
|
|
|
- if (rowitem.Ch2 != valueStr) rowitem.Ch2 = valueStr;
|
|
|
|
- break;
|
|
|
|
- case 3:
|
|
|
|
- if (rowitem.Ch3 != valueStr) rowitem.Ch3 = valueStr;
|
|
|
|
- break;
|
|
|
|
- case 4:
|
|
|
|
- if (rowitem.Ch4 != valueStr) rowitem.Ch4 = valueStr;
|
|
|
|
- break;
|
|
|
|
- case 5:
|
|
|
|
- if (rowitem.Ch5 != valueStr) rowitem.Ch5 = valueStr;
|
|
|
|
- break;
|
|
|
|
- case 6:
|
|
|
|
- if (rowitem.Ch6 != valueStr) rowitem.Ch6 = valueStr;
|
|
|
|
- break;
|
|
|
|
- case 7:
|
|
|
|
- if (rowitem.Ch7 != valueStr) rowitem.Ch7 = valueStr;
|
|
|
|
- break;
|
|
|
|
- case 8:
|
|
|
|
- if (rowitem.Ch8 != valueStr) rowitem.Ch8 = valueStr;
|
|
|
|
- break;
|
|
|
|
- case 9:
|
|
|
|
- if (rowitem.Ch9 != valueStr) rowitem.Ch9 = valueStr;
|
|
|
|
- break;
|
|
|
|
- case 10:
|
|
|
|
- if (rowitem.Ch10 != valueStr) rowitem.Ch10 = valueStr;
|
|
|
|
- break;
|
|
|
|
- case 11:
|
|
|
|
- if (rowitem.Ch11 != valueStr) rowitem.Ch11 = valueStr;
|
|
|
|
- break;
|
|
|
|
- case 12:
|
|
|
|
- if (rowitem.Ch12 != valueStr) rowitem.Ch12 = valueStr;
|
|
|
|
- break;
|
|
|
|
- case 13:
|
|
|
|
- if (rowitem.Ch13 != valueStr) rowitem.Ch13 = valueStr;
|
|
|
|
- break;
|
|
|
|
- case 14:
|
|
|
|
- if (rowitem.Ch14 != valueStr) rowitem.Ch14 = valueStr;
|
|
|
|
- break;
|
|
|
|
- case 15:
|
|
|
|
- if (rowitem.Ch15 != valueStr) rowitem.Ch15 = valueStr;
|
|
|
|
- break;
|
|
|
|
- case 16:
|
|
|
|
- if (rowitem.Ch16 != valueStr) rowitem.Ch16 = valueStr;
|
|
|
|
- break;
|
|
|
|
- default:
|
|
|
|
- break;
|
|
|
|
|
|
+ valueStr = value switch
|
|
|
|
+ {
|
|
|
|
+ (ushort)TcBorken.Normal => TcBorken.Normal.ToString(),
|
|
|
|
+ (ushort)TcBorken.Error => TcBorken.Error.ToString(),
|
|
|
|
+ _ => throw new NotImplementedException(),
|
|
|
|
+ };
|
|
}
|
|
}
|
|
- });
|
|
|
|
|
|
+ else if (pointName == "ActiveTuneSet")
|
|
|
|
+ {
|
|
|
|
+ valueStr = value switch
|
|
|
|
+ {
|
|
|
|
+ (ushort)ActiveTuneSet.AutoTune => ActiveTuneSet.AutoTune.ToString(),
|
|
|
|
+ (ushort)ActiveTuneSet.Running => ActiveTuneSet.Running.ToString(),
|
|
|
|
+ _ => throw new NotImplementedException(),
|
|
|
|
+ };
|
|
|
|
+ }
|
|
|
|
+ else if (pointName == "Inhibit")
|
|
|
|
+ {
|
|
|
|
+ valueStr = value switch
|
|
|
|
+ {
|
|
|
|
+ (ushort)Inhibit.Enable => Inhibit.Enable.ToString(),
|
|
|
|
+ (ushort)Inhibit.Disable => Inhibit.Disable.ToString(),
|
|
|
|
+ _ => throw new NotImplementedException(),
|
|
|
|
+ };
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ valueStr = value.ToString();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (usedRegister == (int)DataType.Float)
|
|
|
|
+ {
|
|
|
|
+ uint intValue = Convert.ToUInt32(valueStr, 2);
|
|
|
|
+ byte[] bytes = BitConverter.GetBytes(intValue);
|
|
|
|
+ var value = BitConverter.ToSingle(bytes, 0);
|
|
|
|
+ valueStr = value.ToString();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ var rowitem = RowItems.First(item => item.Name == pointName);
|
|
|
|
+ switch (chNumber)
|
|
|
|
+ {
|
|
|
|
+ case 1:
|
|
|
|
+ if (rowitem.Ch1 != valueStr) rowitem.Ch1 = valueStr;
|
|
|
|
+ break;
|
|
|
|
+ case 2:
|
|
|
|
+ if (rowitem.Ch2 != valueStr) rowitem.Ch2 = valueStr;
|
|
|
|
+ break;
|
|
|
|
+ case 3:
|
|
|
|
+ if (rowitem.Ch3 != valueStr) rowitem.Ch3 = valueStr;
|
|
|
|
+ break;
|
|
|
|
+ case 4:
|
|
|
|
+ if (rowitem.Ch4 != valueStr) rowitem.Ch4 = valueStr;
|
|
|
|
+ break;
|
|
|
|
+ case 5:
|
|
|
|
+ if (rowitem.Ch5 != valueStr) rowitem.Ch5 = valueStr;
|
|
|
|
+ break;
|
|
|
|
+ case 6:
|
|
|
|
+ if (rowitem.Ch6 != valueStr) rowitem.Ch6 = valueStr;
|
|
|
|
+ break;
|
|
|
|
+ case 7:
|
|
|
|
+ if (rowitem.Ch7 != valueStr) rowitem.Ch7 = valueStr;
|
|
|
|
+ break;
|
|
|
|
+ case 8:
|
|
|
|
+ if (rowitem.Ch8 != valueStr) rowitem.Ch8 = valueStr;
|
|
|
|
+ break;
|
|
|
|
+ case 9:
|
|
|
|
+ if (rowitem.Ch9 != valueStr) rowitem.Ch9 = valueStr;
|
|
|
|
+ break;
|
|
|
|
+ case 10:
|
|
|
|
+ if (rowitem.Ch10 != valueStr) rowitem.Ch10 = valueStr;
|
|
|
|
+ break;
|
|
|
|
+ case 11:
|
|
|
|
+ if (rowitem.Ch11 != valueStr) rowitem.Ch11 = valueStr;
|
|
|
|
+ break;
|
|
|
|
+ case 12:
|
|
|
|
+ if (rowitem.Ch12 != valueStr) rowitem.Ch12 = valueStr;
|
|
|
|
+ break;
|
|
|
|
+ case 13:
|
|
|
|
+ if (rowitem.Ch13 != valueStr) rowitem.Ch13 = valueStr;
|
|
|
|
+ break;
|
|
|
|
+ case 14:
|
|
|
|
+ if (rowitem.Ch14 != valueStr) rowitem.Ch14 = valueStr;
|
|
|
|
+ break;
|
|
|
|
+ case 15:
|
|
|
|
+ if (rowitem.Ch15 != valueStr) rowitem.Ch15 = valueStr;
|
|
|
|
+ break;
|
|
|
|
+ case 16:
|
|
|
|
+ if (rowitem.Ch16 != valueStr) rowitem.Ch16 = valueStr;
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
private void Initialize()
|
|
private void Initialize()
|
|
{
|
|
{
|
|
- if(_slaveId<=0)
|
|
|
|
|
|
+ if (_slaveId <= 0)
|
|
{
|
|
{
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
@@ -230,20 +336,20 @@ public partial class Mini8TabViewModel : ObservableObject
|
|
AddData(nameof(ch.Value.Running_P), ch.Key, ch.Value.Running_P, DataType.Float);
|
|
AddData(nameof(ch.Value.Running_P), ch.Key, ch.Value.Running_P, DataType.Float);
|
|
AddData(nameof(ch.Value.Running_I), ch.Key, ch.Value.Running_I, DataType.Float);
|
|
AddData(nameof(ch.Value.Running_I), ch.Key, ch.Value.Running_I, DataType.Float);
|
|
AddData(nameof(ch.Value.Running_D), ch.Key, ch.Value.Running_D, DataType.Float);
|
|
AddData(nameof(ch.Value.Running_D), ch.Key, ch.Value.Running_D, DataType.Float);
|
|
- AddData(nameof(ch.Value.Inhibit), ch.Key, ch.Value.Inhibit, DataType.Float);
|
|
|
|
|
|
+ AddData(nameof(ch.Value.Inhibit), ch.Key, ch.Value.Inhibit, DataType.UShort);
|
|
AddData(nameof(ch.Value.ActiveAutoTune), ch.Key, ch.Value.ActiveAutoTune, DataType.Float);
|
|
AddData(nameof(ch.Value.ActiveAutoTune), ch.Key, ch.Value.ActiveAutoTune, DataType.Float);
|
|
AddData(nameof(ch.Value.SetpointUpRate), ch.Key, ch.Value.SetpointUpRate, DataType.Float);
|
|
AddData(nameof(ch.Value.SetpointUpRate), ch.Key, ch.Value.SetpointUpRate, DataType.Float);
|
|
AddData(nameof(ch.Value.SetpointDownRate), ch.Key, ch.Value.SetpointDownRate, DataType.Float);
|
|
AddData(nameof(ch.Value.SetpointDownRate), ch.Key, ch.Value.SetpointDownRate, DataType.Float);
|
|
- AddData(nameof(ch.Value.Caps), ch.Key, ch.Value.Caps, DataType.Double);
|
|
|
|
- AddData(nameof(ch.Value.Floor), ch.Key, ch.Value.Floor, DataType.Double);
|
|
|
|
- AddData(nameof(ch.Value.CapsWarning), ch.Key, ch.Value.CapsWarning, DataType.Double);
|
|
|
|
- AddData(nameof(ch.Value.FloorWarning), ch.Key, ch.Value.FloorWarning, DataType.Double);
|
|
|
|
|
|
+ AddData(nameof(ch.Value.Caps), ch.Key, ch.Value.Caps, DataType.UShort);
|
|
|
|
+ AddData(nameof(ch.Value.Floor), ch.Key, ch.Value.Floor, DataType.UShort);
|
|
|
|
+ AddData(nameof(ch.Value.CapsWarning), ch.Key, ch.Value.CapsWarning, DataType.UShort);
|
|
|
|
+ AddData(nameof(ch.Value.FloorWarning), ch.Key, ch.Value.FloorWarning, DataType.UShort);
|
|
}
|
|
}
|
|
|
|
|
|
_timer.Start();
|
|
_timer.Start();
|
|
}
|
|
}
|
|
|
|
|
|
- private void AddData(string name, byte key, ushort value,DataType dataType)
|
|
|
|
|
|
+ private void AddData(string name, byte key, ushort value, DataType dataType)
|
|
{
|
|
{
|
|
if (!_pointNamePosition.ContainsKey(name))
|
|
if (!_pointNamePosition.ContainsKey(name))
|
|
{
|
|
{
|