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 { const int FlowIntervalSec = 10; #region IWeightSystemService 接口 public ObservableCollection Items { get; } = new ObservableCollection(); public WeighterAccessory Accessory { get; } = new WeighterAccessory(); private PLCProxySystem plcos = new PLCProxySystem(); /// /// PLC代理系统 /// public IPLCProxySystemService PLCos { get { return plcos; } } /// /// 层数 /// public int ItemsCnt { get; private set; } = 3; #endregion string[] NumberNames; /// /// 报警系统 /// WarningSystem2 warning; /// /// 记录到数据库 /// HistoryDb historyDb; /// /// 报警配置 /// ErrorConf errorConf; /// /// 周期保存Ibc数据 /// PeriodicallySaveData psdFlow; public WeightSystem() { if (!LoadNumberNames()) SaveNumberNames(); //-------------------------------------------------------------------------------- //step 1 加载PLC寄存器 文件 AddConfigFile(); } public void Init(HistoryDb historyDb, WarningSystem2 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; // } // } //}); //step 3 历史数据记录 //添加任务 for (int i = 0; i < Items.Count(); i++) { List props = new List { 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(); psdFlow.Init( FlowIntervalSec, this.historyDb.AddFlowRange, () => { if (!PLCos.IsConnectedWithPLC) return null; 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 objnames = new Dictionary(); 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_number = "weight2NumberNames.json"; bool LoadNumberNames() { if (!File.Exists(filePath_number)) return false; string json = File.ReadAllText(filePath_number); var p = Newtonsoft.Json.JsonConvert.DeserializeObject(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(ItemsCnt) }; } public string[] GetNoSyncPropNames() { return null; } } public class NumberNamesJsonDb { public string[] NumberNames; } }