using Edge.Core.Processor; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Text.Json; using System.Threading.Tasks; using GasConcentrations_Yt95h.MessageEntity; using GasConcentrations_Yt95h.MessageEntity.Incoming; using GasConcentrations_Yt95h.MessageEntity.Outgoing; namespace GasConcentrations_Yt95h { public class SensorHandler { public byte DeviceAddress { get; set; } public EventHandler OnJsonDataRecieved; private IContext context; private readonly Queue presetRequestQueue = new Queue(); private ILogger logger = null; private DeviceState deviceState = DeviceState.Disconnected; public SensorHandler(byte deviceAddress, ILogger logger) { DeviceAddress = deviceAddress; this.logger = logger; logger.LogInformation($"Create sensor handler with deviceAddress: {deviceAddress}"); } public void Init(IContext context) { this.context = context; this.context.Incoming.OnLongTimeNoSeeMessage += (_, __) => { this.deviceState = DeviceState.Disconnected; FireStateChange(this.deviceState); }; this.context.Incoming.LongTimeNoSeeMessageTimeout = 6000; } public void PresetRegister(short lowAlarm, short highAlarm) { if (presetRequestQueue.Count < 8) { presetRequestQueue.Enqueue(new PresetSingleRegister_Request(this.DeviceAddress, 8, lowAlarm)); presetRequestQueue.Enqueue(new PresetSingleRegister_Request(this.DeviceAddress, 10, highAlarm)); } } public MessageBase GetRequestMessage() { switch (this.deviceState) { case DeviceState.Connected: { if (presetRequestQueue.Count > 0) { return presetRequestQueue.Dequeue(); } else return new ReadConcentration_Request(this.DeviceAddress); } case DeviceState.Disconnected: { return new ReadConcentration_Request(this.DeviceAddress); } default: { return null; } }; } public Task Process(IContext context) { if (this.deviceState != DeviceState.Connected) { this.deviceState = DeviceState.Connected; FireStateChange(this.deviceState); } FireDataRecieved(context.Incoming.Message); return Task.CompletedTask; } private void FireDataRecieved(MessageBase message) { dynamic response = null; switch (message.FunctionCode) { case FunctionCode.READ_HOLDING_REGISTERS: response = message as ReadRegisters_Response; logger.LogInformation($"Device: {DeviceAddress}, received response message with" + $" Concentration {response.Concentration.ToString("f2")}, GasType {response.GasType}, Unit {response.Unit}, AlarmType {response.AlarmType}"); OnJsonDataRecieved?.Invoke(this, JsonSerializer.Serialize(new { DeviceAddress = this.DeviceAddress, Concentration = response.Concentration })); break; default: logger.LogError($"Unexpected respone msg type: {message.GetType().FullName}"); break; } } private void FireStateChange(DeviceState deviceState) { logger.LogInformation($"Device: {this.DeviceAddress}, DeviceState is {deviceState}"); OnJsonDataRecieved?.Invoke(this, JsonSerializer.Serialize(new { DeviceAddress = this.DeviceAddress, DeviceState = deviceState.ToString() })); } } }