using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Linq; using System.Runtime.CompilerServices; using Newtonsoft.Json; using TeamAAS.Feeder.Enums; namespace TeamAAS.Feeder.Models { /// /// 单个电机参数(振幅 / 频率 / 相位 / 波形) /// public class VoiceMotorParam : INotifyPropertyChanged { private ushort _amplitude = 50; private ushort _frequency = 100; private ushort _phase = 0; private WaveShape _waveShape = WaveShape.SignWave; [Category("电机参数"), DisplayName("振幅(0-100%)")] public ushort Amplitude { get { return _amplitude; } set { SetProperty(ref _amplitude, value); } } [Category("电机参数"), DisplayName("频率(0-250Hz)")] public ushort Frequency { get { return _frequency; } set { SetProperty(ref _frequency, value); } } [Category("电机参数"), DisplayName("相位(0-359°)")] public ushort Phase { get { return _phase; } set { SetProperty(ref _phase, value); } } [Category("电机参数"), DisplayName("波形")] public WaveShape WaveShape { get { return _waveShape; } set { if (SetProperty(ref _waveShape, value)) { OnPropertyChanged(nameof(IsWaveNone)); OnPropertyChanged(nameof(IsWaveSin)); OnPropertyChanged(nameof(IsWaveSaw)); OnPropertyChanged(nameof(IsWaveTri)); } } } [JsonIgnore, Category("电机参数")] public bool IsWaveNone { get { return _waveShape == WaveShape.None; } set { if (value) WaveShape = WaveShape.None; } } [JsonIgnore, Category("电机参数")] public bool IsWaveSin { get { return (_waveShape & WaveShape.SignWave) != 0; } set { WaveShape = value ? (_waveShape | WaveShape.SignWave) : (_waveShape & ~WaveShape.SignWave); } } [JsonIgnore, Category("电机参数")] public bool IsWaveSaw { get { return (_waveShape & WaveShape.SawToothWave) != 0; } set { WaveShape = value ? (_waveShape | WaveShape.SawToothWave) : (_waveShape & ~WaveShape.SawToothWave); } } [JsonIgnore, Category("电机参数")] public bool IsWaveTri { get { return (_waveShape & WaveShape.TriangleWave) != 0; } set { WaveShape = value ? (_waveShape | WaveShape.TriangleWave) : (_waveShape & ~WaveShape.TriangleWave); } } public VoiceMotorParam Clone() { return new VoiceMotorParam { Amplitude = Amplitude, Frequency = Frequency, Phase = Phase, WaveShape = WaveShape, }; } public event PropertyChangedEventHandler PropertyChanged; protected virtual bool SetProperty(ref T storage, T value, [CallerMemberName] string propertyName = null) { if (EqualityComparer.Default.Equals(storage, value)) return false; storage = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); return true; } protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } /// /// 单个振动动作参数 = 4 个电机 + 持续时间 /// public class SingleActionParam : INotifyPropertyChanged { public VoiceMotorParam Motor1 { get; set; } = new VoiceMotorParam(); public VoiceMotorParam Motor2 { get; set; } = new VoiceMotorParam(); public VoiceMotorParam Motor3 { get; set; } = new VoiceMotorParam(); public VoiceMotorParam Motor4 { get; set; } = new VoiceMotorParam(); private int _durationValue = 500; [Category("动作参数"), DisplayName("持续时间(ms)")] public int DurationValue { get { return _durationValue; } set { SetProperty(ref _durationValue, value); } } public SingleActionParam Clone() { return new SingleActionParam { Motor1 = Motor1.Clone(), Motor2 = Motor2.Clone(), Motor3 = Motor3.Clone(), Motor4 = Motor4.Clone(), DurationValue = DurationValue, }; } public event PropertyChangedEventHandler PropertyChanged; protected virtual bool SetProperty(ref T storage, T value, [CallerMemberName] string propertyName = null) { if (EqualityComparer.Default.Equals(storage, value)) return false; storage = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); return true; } } /// /// 供料器配置信息(设备 + 完整振动参数) /// public class FeederInfo : INotifyPropertyChanged { private Guid _id = Guid.NewGuid(); private int _feederNo; private string _feederName = ""; private FeederBrand _feederBrand = FeederBrand.Team; private FeederConnectType _connectType = FeederConnectType.TCP; private string _ip = "192.168.31.200"; private int _port = 5000; private string _serialPortName = "COM3"; private int _baudRate = 115200; private bool _isConnected; private bool _isBacklightOn; [Browsable(false)] public Guid Id { get { return _id; } set { SetProperty(ref _id, value); } } [Category("基本"), DisplayName("编号")] public int FeederNo { get { return _feederNo; } set { SetProperty(ref _feederNo, value); } } [Category("基本"), DisplayName("名称")] public string FeederName { get { return _feederName; } set { SetProperty(ref _feederName, value); } } [Category("只读信息"), DisplayName("品牌"), ReadOnly(true)] public FeederBrand FeederBrand { get { return _feederBrand; } set { if (SetProperty(ref _feederBrand, value)) { // Team 品牌只支持 TCP 连接,切品牌时自动纠正连接方式 if (value == FeederBrand.Team && ConnectType != FeederConnectType.TCP) ConnectType = FeederConnectType.TCP; } } } [Category("通讯"), DisplayName("连接方式")] public FeederConnectType ConnectType { get { return _connectType; } set { SetProperty(ref _connectType, value); } } [Category("通讯"), DisplayName("IP地址")] public string IP { get { return _ip; } set { SetProperty(ref _ip, value); } } [Category("通讯"), DisplayName("端口")] public int Port { get { return _port; } set { SetProperty(ref _port, value); } } [Category("通讯"), DisplayName("串口号")] public string SerialPortName { get { return _serialPortName; } set { SetProperty(ref _serialPortName, value); } } [Category("通讯"), DisplayName("波特率")] public int BaudRate { get { return _baudRate; } set { SetProperty(ref _baudRate, value); } } [Browsable(false)] [JsonIgnore] public bool IsConnected { get { return _isConnected; } set { SetProperty(ref _isConnected, value); } } [Browsable(false)] [JsonIgnore] public bool IsBacklightOn { get { return _isBacklightOn; } set { SetProperty(ref _isBacklightOn, value); } } /// /// 11 个振动动作组(A~K,对应 FeederAction 0~10) /// public ObservableCollection ActionGroups { get; set; } = new ObservableCollection( Enumerable.Range(0, 11).Select(_ => new SingleActionParam())); /// /// 多个送料流程(序列集) /// public ObservableCollection Sequences { get; set; } = new ObservableCollection(); public FeederInfo Clone() { var json = JsonConvert.SerializeObject(this); return JsonConvert.DeserializeObject(json); } public event PropertyChangedEventHandler PropertyChanged; protected virtual bool SetProperty(ref T storage, T value, [CallerMemberName] string propertyName = null) { if (EqualityComparer.Default.Equals(storage, value)) return false; storage = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); return true; } } }