using FLY.OBJComponents.IService; using FLY.OBJComponents.Server; using FLY.Weight2.Common; using FLY.Weight2.IService; using FLY.Weight2.Server.Model; using FObjBase; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Linq; using System.Text.RegularExpressions; using FLY.Modbus; namespace FLY.Weight2.Server { public class WeightSystem : IWeightSystemService, IPropertyOpt { #region IWeightSystemService 接口 public ObservableCollection<WeighterC> Items { get; } = new ObservableCollection<WeighterC>(); public WeighterAccessory Accessory { get; } = new WeighterAccessory(); private PLCProxySystem plcos = new PLCProxySystem(); /// <summary> /// PLC代理系统 /// </summary> public IPLCProxySystemService PLCos { get { return plcos; } } private int flowInterval = 10; /// <summary> /// 流量记录周期,单位s, 最小值为5 /// </summary> public int FlowInterval { get { return flowInterval; } set { if (value < 5) value = 5; if (flowInterval != value) { flowInterval = value; } } } /// <summary> /// 层数 /// </summary> public int ItemsCnt { get; private set; } = 3; #endregion string[] NumberNames; /// <summary> /// 报警系统 /// </summary> WarningSystem warning; /// <summary> /// 记录到数据库 /// </summary> HistoryDb historyDb; /// <summary> /// 报警配置 /// </summary> ErrorConf errorConf; /// <summary> /// 周期保存Ibc数据 /// </summary> PeriodicallySaveData<Lc_Flow> psdFlow; public WeightSystem() { if (!LoadNumberNames()) SaveNumberNames(); Load(); //-------------------------------------------------------------------------------- //step 1 加载PLC寄存器 文件 AddConfigFile(); } public void Init(HistoryDb historyDb, WarningSystem warning) { this.historyDb = historyDb; this.warning = warning; //-------------------------------------------------------------------------------- //step 2 报警配置 errorConf = new ErrorConf(PLCos, this.warning, "称重"); errorConf.AddErrorAction(Accessory); for (int i = 0; i < Items.Count(); i++) { errorConf.AddErrorAction( Items[i], (ref string description, object state) => { int idx = (int)state; description = Items[idx].Number + "层 " + description; }, i); } errorConf.InitError(); //报警使能 Misc.BindingOperations.SetBinding(Accessory, nameof(Accessory.AlarmIsOn), () => { this.warning.Enable = !Accessory.AlarmIsOn; }); Misc.BindingOperations.SetBinding(this.warning, nameof(this.warning.Enable), () => { Accessory.AlarmIsOn = !this.warning.Enable; }); //报警复位呢? //Misc.BindingOperations.SetBinding(this.warning, "IsRinging", () => //{ // if (!this.warning.IsRinging) // { // for (int i = 0; i < ItemsCnt; i++) // { // Items[i].IsAlarmReseted = false; // } // } //}); //-------------------------------------------------------------------------------- this.PropertyChanged += (s, e) => { if (e.PropertyName == nameof(FlowInterval)) { Save(); } }; //step 3 历史数据记录 //添加任务 for (int i = 0; i < Items.Count(); i++) { List<string> props = new List<string> { nameof(WeighterC.CurrentFlow), nameof(WeighterC.ScrewPDisp), nameof(WeighterC.ScrewMotorFreq) }; PLCos.SetPlan($"{nameof(Items)}[{i}]", props, 0); } PLCos.SetPlan(nameof(Accessory), new string[] { nameof(Accessory.TotalFlow) }, 0); psdFlow = new PeriodicallySaveData<Lc_Flow>(); psdFlow.Init( FlowInterval, this.historyDb.AddFlowRange, () => { if (!PLCos.IsConnectedWithPLC) return null; var v = Items[0].BinWeight; var v1 = Items[1].BinWeight; var v2 = Items[2].BinWeight; if (Accessory.TotalFlow < 5)//没有生产 return null; //记录数据 Lc_Flow lc_Flow = new Lc_Flow { Time = DateTime.Now, Total = Math.Round(Accessory.TotalFlow, 4), Items = new Lc_FlowItem[Items.Count] }; for (int i = 0; i < Items.Count; i++) { lc_Flow.Items[i] = new Lc_FlowItem { Flow = Math.Round(Items[i].CurrentFlow, 4), ScrewPDisp = Math.Round(Items[i].ScrewPDisp, 2), ScrewMotorFreq = Math.Round(Items[i].ScrewMotorFreq, 1) }; } return lc_Flow; }); //-------------------------------------------------------------------------------- //last step PLC 更新计划服务初始化 plcos.Init(); } string GetNumber(int index) { string number; if (NumberNames != null && index < NumberNames.Count() && !string.IsNullOrEmpty(NumberNames[index])) { number = NumberNames[index]; } else { number = ((char)('A' + index)).ToString(); } return number; } void AddConfigFile() { plcos.AddConfigFile("plcgroup.json", (plcgroup) => { //从plcgroup 分析出 有多少层,每层的仓数 int itemsCnt = 0; Regex r = new Regex(@"Items\[([0-9])\]"); foreach (PLCGroup.PLCVariable var in plcgroup.Variables) { Match m = r.Match(var.OwnerName); if (m.Success) { int weighter_idx = int.Parse(m.Groups[1].Value); if (itemsCnt <= weighter_idx)//记录最大值 itemsCnt = weighter_idx + 1; } } ItemsCnt = itemsCnt; for (int i = 0; i < ItemsCnt; i++) { string number = GetNumber(i); WeighterC w = new WeighterC(number, i); Items.Add(w); } //objname 转 obj Dictionary<string, INotifyPropertyChanged> objnames = new Dictionary<string, INotifyPropertyChanged>(); objnames.Add(nameof(Accessory), Accessory); for (int i = 0; i < ItemsCnt; i++) objnames.Add($"{nameof(Items)}[{i}]", Items[i]); return objnames; }); //这个是从测厚仪获取的,每几秒就写一次,不调试!!!!! plcos.IgnoreLogProperties.Add(new SenderProperty() { sender = Accessory, propertyName = nameof(Accessory.CurrentVelocitySet) }); } public event PropertyChangedEventHandler PropertyChanged; string filepath = "weight2.json"; void Save() { WeightSystemJsonDb p = new WeightSystemJsonDb() { FlowInterval = FlowInterval }; string json = JsonConvert.SerializeObject(p, Newtonsoft.Json.Formatting.Indented); File.WriteAllText(filepath, json); } void Load() { if (!File.Exists(filepath)) return; try { string json = File.ReadAllText(filepath); JsonConvert.PopulateObject(json, this); } catch { } } string filePath_number = "weight2NumberNames.json"; bool LoadNumberNames() { if (!File.Exists(filePath_number)) return false; string json = File.ReadAllText(filePath_number); var p = Newtonsoft.Json.JsonConvert.DeserializeObject<NumberNamesJsonDb>(json); NumberNames = p.NumberNames; return true; } void SaveNumberNames() { NumberNamesJsonDb jsonDb = new NumberNamesJsonDb { NumberNames = NumberNames }; string json = Newtonsoft.Json.JsonConvert.SerializeObject(jsonDb); File.WriteAllText(filePath_number, json); } public string[] GetSyncPropNames() { return new string[]{ nameof(FlowInterval), nameof(ItemsCnt) }; } public string[] GetNoSyncPropNames() { return null; } } public class WeightSystemJsonDb { public int FlowInterval { get; set; } } public class NumberNamesJsonDb { public string[] NumberNames; } }