using Edge.Core.IndustryStandardInterface.ATG; using Edge.Core.Processor; using Edge.Core.Processor.Dispatcher.Attributes; using Edge.Core.UniversalApi; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace Bogus_ATG { [UniversalApi(Name = "OnStateChange", EventDataType = typeof(AtgStateChangeEventArg))] [UniversalApi(Name = "OnAlarm", EventDataType = typeof(AtgAlarmEventArg))] [MetaPartsDescriptor( "lang-zh-cn:液位仪模拟器lang-en-us:ATG Simulator", "lang-zh-cn:用于模拟液位仪(可配置多个油罐), 每个虚拟油罐数据会自动变化lang-en-us:Used for simulate Auto Tank Gauge which have multiple tanks linked, each virutal tank has its data updated randomly and timely", new[] { "lang-zh-cn:液位仪lang-en-us:ATG" })] public class App : IAutoTankGaugeController, IAppProcessor, IDisposable { private IEnumerable tanks; public string MetaConfigName { get; set; } public int DeviceId => 1; public IEnumerable Tanks { get; set; } public AtgState State => AtgState.Idle; public SystemUnit SystemUnit => SystemUnit.Metric; public event EventHandler OnStateChange; public event EventHandler OnAlarm; public App(int tanksCount) { this.tanks = Enumerable.Range(1, tanksCount).Select(i => { Tank tank = new Tank(); tank.TankNumber = (byte)i; tank.Diameter = 2000.0 + i * 200; tank.Label = "我是油罐" + i + "的标签"; Product product = new Product(); product.ProductCode = (i == 1 ? 0 : (i + 90)).ToString(); product.ProductLabel = (i == 1 ? 0 : (i + 90)) + "#"; tank.Product = product; TankLimit tankLimit = new TankLimit(); tankLimit.FullVolume = 3000.0 + i * 150; tankLimit.FuelTemperatureHighLimit = (60.0); tankLimit.FuelTemperatureLowLimit = (10.0); tankLimit.HighProduct = (0.85) + i * 0.05; tankLimit.HighWaterAlarm = (100.0); tankLimit.HighWaterWarning = (50.0); tankLimit.LowProduct = (25.0) + i * 2; tankLimit.MaxVolume = 2700.0 + i * 150; tank.Limit = tankLimit; Probe probe = new Probe(); probe.ProbeLength = 2000.0 + i * 150; probe.ProbeOffset = (1.0); probe.WaterOffset = (3.0); probe.DeviceId = (i); tank.Probe = probe; return tank; }); this.Tanks = this.tanks; } public void Dispose() { } [UniversalApi()] public Task> GetTanksAsync() { return Task.FromResult(this.tanks); } /// /// /// /// 0 or null for query all tanks /// [UniversalApi(Description = "", InputParametersExampleJson = "[1]")] public async Task GetTankReadingAsync(int tankNumber) { TankReading tankReading = new TankReading(); tankReading.Density = 1.0; tankReading.Height = new Random().Next(200, 1800); tankReading.TcVolume = new Random().Next(200, 1800); tankReading.Ullage = new Random().Next(100, 500); tankReading.Volume = new Random().Next(200, 1800); tankReading.Water = new Random().Next(10, 150); tankReading.WaterVolume = new Random().Next(10, 150); tankReading.Temperature = new Random().Next(1, 100); tankReading.TankNumber = tankNumber; return await Task.FromResult(tankReading); } [UniversalApi(Description = "", InputParametersExampleJson = "[1,8,0,\"2020-04-01T18:25:43.511Z\"]")] public Task> GetTankDeliveryAsync(int tankNumber, int pageRowCount = 10, int pageIndex = 0, DateTime? filterTimestamp = null) { return Task.FromResult(Enumerable.Range(1, pageRowCount).Select(i => { Delivery delivery = new Delivery(); delivery.TankNumber = (byte)tankNumber; delivery.StartingDateTime = DateTime.Now.Subtract(new TimeSpan(i, 0, 0)); delivery.EndingDateTime = DateTime.Now.Subtract(new TimeSpan(0, i, 0)); delivery.StartingFuelHeight = 1.0 + i * 10; delivery.EndingFuelHeight = 3000.0 + i * 100; delivery.Description = "man made fake Delivery for tank: " + tankNumber; return delivery; })); } [UniversalApi(Description = "", InputParametersExampleJson = "[1,8,0,\"2020-04-01T18:25:43.511Z\"]")] public async Task> GetTankInventoryAsync(int tankNumber, int pageRowCount = 10, int pageIndex = 0, DateTime? filterTimestamp = null) { var reading = await this.GetTankReadingAsync(tankNumber); if (reading == null) return null; var inventory = new Inventory() { TankNumber = tankNumber, FuelHeight = reading.Height ?? -1, FuelVolume = reading.Volume ?? -1, FuelTCVolume = reading.TcVolume ?? -1, WaterHeight = reading.Water ?? -1, Temperture = reading.Temperature ?? int.MinValue, TimeStamp = DateTime.Now, }; return new[] { inventory }; } [UniversalApi(Description = "", InputParametersExampleJson = "[1,8,0,\"2020-04-01T18:25:43.511Z\"]")] public Task> GetTankAlarmAsync(int tankNumber, int pageRowCount = 10, int pageIndex = 0, DateTime? filterTimestamp = null) { return Task.FromResult(Enumerable.Range(1, pageRowCount).Select(i => { Alarm alarm = new Alarm(); alarm.Id = i; alarm.CreatedTimeStamp = DateTime.Now.Subtract(new TimeSpan(i, 0, 0)); alarm.Priority = AlarmPriority.Alarm; alarm.TankNumber = (byte)tankNumber; alarm.Type = AlarmType.TankHighProductAlarm; alarm.Description = "man made fake Alarm for tank: " + tankNumber; return alarm; })); } public void Init(IEnumerable processors) { } [UniversalApi] public Task> GetTanksReadingAsync() { return Task.FromResult(Enumerable.Range(1, this.tanks.Count()).Select(i => { TankReading tankReading = new TankReading(); tankReading.Density = 1.0; tankReading.Height = new Random().Next(200, 1800); tankReading.TcVolume = new Random().Next(200, 1800); tankReading.Ullage = new Random().Next(100, 500); tankReading.Volume = new Random().Next(200, 1800); tankReading.Water = new Random().Next(10, 150); tankReading.WaterVolume = new Random().Next(10, 150); tankReading.Temperature = new Random().Next(1, 100); tankReading.TankNumber = i; return tankReading; })); } } }