private async Task UpdateRtuMapAsync(ContainerEntity entity, string connectionString, string container, string filename) { RtuMap map = await RtuMap.LoadAsync(connectionString, container, filename); map = map ?? new RtuMap(); map.Name = map.Name ?? entity.VirtualRtuId; foreach (var slave in entity.Slaves) { if (map.HasItem(slave.UnitId)) { map.Remove(slave.UnitId); } string requestUriString = UriGenerator.GetRtuPiSystem(entity.Hostname, entity.VirtualRtuId, entity.DeviceId, slave.UnitId, true); string responseUriString = UriGenerator.GetRtuPiSystem(entity.Hostname, entity.VirtualRtuId, entity.DeviceId, slave.UnitId, false); if (slave.Constraints != null && slave.Constraints.Count == 0) { slave.Constraints = null; } map.Add(slave.UnitId, requestUriString, responseUriString, slave.Constraints); } await map.UpdateAsync(connectionString, container, filename); }
private void Input_OnReceive(object sender, ChannelReceivedEventArgs e) { MbapHeader header = MbapHeader.Decode(e.Message); if (header == null) { logger?.LogWarning("MBAP Header returned null"); return; //assume keep alive } if (!map.HasItem(header.UnitId)) { byte[] errorMsg = ModbusErrorMessage.Create(e.Message, ErrorCode.GatewayPathsNotAvailable); this.InputChannel.SendAsync(errorMsg).GetAwaiter(); return; } if (!map.GetItem(header.UnitId).Authorize(e.Message)) { byte[] errorMsg = ModbusErrorMessage.Create(e.Message, ErrorCode.IllegalAddress); this.InputChannel.SendAsync(errorMsg).GetAwaiter(); return; } byte[] message = e.Message; byte[] msg = null; foreach (var filter in InputFilters) { msg = filter.Execute(message); msg ??= message; } OutputChannel.SendAsync(msg).GetAwaiter(); }
public async Task SendAsync(byte[] message) { if (client == null || !client.IsConnected) { logger?.LogWarning("MQTT client is not available to forward message."); return; } try { MbapHeader header = MbapHeader.Decode(message); if (map.HasItem(header.UnitId)) { if (!subscriptions.Contains(header.UnitId)) { string resource = map.GetItem(header.UnitId).RtuOutputEvent; await client.SubscribeAsync(resource, QualityOfServiceLevelType.AtMostOnce, ModbusMessageReceived); logger?.LogInformation( $"MQTT client channel subscribed {resource} with Unit ID = {header.UnitId}"); subscriptions.Add(header.UnitId); } cache.Add(GetCacheKey(header), new Tuple <ushort, byte[]>(header.TransactionId, message), 20.0); string pisystem = map.GetItem(header.UnitId).RtuInputEvent; await client.PublishAsync(QualityOfServiceLevelType.AtMostOnce, pisystem, "application/octet-stream", message); logger?.LogDebug($"VRTU published to {pisystem}"); await diag?.PublishInput(header); } else { logger?.LogWarning($"Unit Id = {header.UnitId} in Modbus message not found in RTU map."); } } catch (Exception ex) { logger?.LogError(ex, "Fault sending MQTT client channel."); } }