Example #1
0
        private void Channel_OnReceive(object sender, ChannelReceivedEventArgs e)
        {
            try
            {
                MbapHeader header = MbapHeader.Decode(e.Message);

                if (!unitId.HasValue)
                {
                    unitId = header.UnitId;
                }

                if (unitId.HasValue && header.UnitId == unitId.Value)
                {
                    RtuPiSystem piSystem = map.GetItem((ushort)unitId.Value);

                    if (piSystem == null)
                    {
                        throw new Exception($"PI-System not found for unit id - {unitId.Value}");
                    }
                    else
                    {
                        client.SubscribeAsync(piSystem.RtuOutputEvent, QualityOfServiceLevelType.AtLeastOnce, ReceiveOutput).GetAwaiter();
                        client.PublishAsync(QualityOfServiceLevelType.AtLeastOnce, piSystem.RtuInputEvent, contentType, e.Message).GetAwaiter();
                    }
                }
                else
                {
                    throw new Exception("Unit Id missing from SCADA client message.");
                }
            }
            catch (Exception ex)
            {
                OnError?.Invoke(this, new AdapterErrorEventArgs(Id, ex));
            }
        }
Example #2
0
        static void SendMessages(Task task)
        {
            try
            {
                if (!send)
                {
                    PrintMessage("Do you want to send messages (Y/N) ? ", ConsoleColor.Cyan, false, true);
                    string sendVal = Console.ReadLine();
                    if (sendVal.ToUpperInvariant() != "Y")
                    {
                        return;
                    }
                }
                send = true;

                PrintMessage("Enter # of messages to send ? ", ConsoleColor.Cyan, false, true);
                string nstring = Console.ReadLine();

                int numMessages = Int32.Parse(nstring);
                PrintMessage("Enter delay between messages in milliseconds ? ", ConsoleColor.Cyan, false, true);
                string dstring = Console.ReadLine().Trim();

                int delayms = Int32.Parse(dstring);

                DateTime startTime = DateTime.Now;
                for (int i = 0; i < numMessages; i++)
                {
                    index++;
                    string payloadString = String.Format($"{DateTime.Now.Ticks}:{name}-message {index}");
                    byte[] payload       = Encoding.UTF8.GetBytes(payloadString);
                    string publishEvent  = !string.IsNullOrEmpty(pubResource) ? pubResource : role == "A" ? resourceA : resourceB;
                    //string publishEvent = role == "A" ? "http://www.skunklab.io/resource-a" : "http://www.skunklab.io/resource-b";
                    Task pubTask = mqttClient.PublishAsync(QualityOfServiceLevelType.AtMostOnce, publishEvent, "text/plain", payload);
                    Task.WhenAll(pubTask);

                    if (delayms > 0)
                    {
                        Task t = Task.Delay(delayms);
                        Task.WaitAll(t);
                    }
                }

                DateTime endTime = DateTime.Now;
                PrintMessage($"Total send time {endTime.Subtract(startTime).TotalMilliseconds} ms", ConsoleColor.White);

                PrintMessage("Send more messages (Y/N) ? ", ConsoleColor.Cyan, false, true);
                string val = Console.ReadLine();
                if (val.ToUpperInvariant() == "Y")
                {
                    SendMessages(task);
                }
            }
            catch (Exception ex)
            {
                PrintMessage("Error", ConsoleColor.Red, true);
                PrintMessage(ex.Message, ConsoleColor.Red);
                Console.ReadKey();
            }
        }
Example #3
0
        public async Task SubscribeAsync(string resource, bool monitor)
        {
            string monitorUriString = null;
            string logUriString     = null;

            string[] parts = resource.Split(new[] { "-" }, StringSplitOptions.RemoveEmptyEntries);
            if (parts.Length == 1)
            {
                //virtual rtu
                monitorUriString = UriGenerator.GetVirtualRtuDiagnosticsPiSystem(hostname, parts[0]);
                logUriString     = UriGenerator.GetVirtualRtuTelemetryPiSystem(hostname, parts[0]);
            }
            else if (parts.Length == 2)
            {
                //module
                monitorUriString = UriGenerator.GetDeviceDiagnosticsPiSystem(hostname, parts[0], parts[1]);
                logUriString     = UriGenerator.GetDeviceTelemetryPiSystem(hostname, parts[0], parts[1]);
            }

            DiagnosticsMessage mevent = new DiagnosticsMessage
            {
                Type = monitor ? DiagnosticsEventType.Native : DiagnosticsEventType.None
            };

            string jsonString = JsonConvert.SerializeObject(mevent);
            await client.PublishAsync(QualityOfServiceLevelType.AtMostOnce, monitorUriString, "application/json",
                                      Encoding.UTF8.GetBytes(jsonString));

            if (monitor)
            {
                if (!subscriptions.Contains(logUriString))
                {
                    subscriptions.Add(logUriString);
                    await client.SubscribeAsync(logUriString, QualityOfServiceLevelType.AtMostOnce, ReceiveLog);
                }
            }
            else
            {
                if (subscriptions.Contains(logUriString))
                {
                    subscriptions.Remove(logUriString);
                    await client.UnsubscribeAsync(logUriString);
                }
            }
        }
Example #4
0
        public async Task PublishOutput(MbapHeader header, ushort transactionId)
        {
            if (!NativeEnabled && !AppInsightsEnabled)
            {
                return;
            }

            DiagnosticsEvent telem = new DiagnosticsEvent(name, header.UnitId, transactionId, header.TransactionId,
                                                          DateTime.UtcNow.ToString("dd-MM-yyyyThh:mm:ss.ffff"));

            if (NativeEnabled && mqttClient.IsConnected)
            {
                string jsonString = JsonConvert.SerializeObject(telem);
                byte[] msg        = Encoding.UTF8.GetBytes(jsonString);
                await mqttClient.PublishAsync(QualityOfServiceLevelType.AtMostOnce, outputPiSystem, "application/json",
                                              msg);
            }

            if (AppInsightsEnabled)
            {
                tclient?.TrackEvent(name, telem.GetEventProperties(), telem.GetEventMetrics());
            }

            if (cache.Contains(transactionId.ToString()))
            {
                Tuple <byte, long> tuple = cache.Get <Tuple <byte, long> >(transactionId.ToString());
                cache.Remove(transactionId.ToString());
                TimeSpan         ts   = TimeSpan.FromTicks(DateTime.Now.Ticks - tuple.Item2);
                DiagnosticsEvent vdts = new DiagnosticsEvent(name, header.UnitId, transactionId, ts.TotalMilliseconds,
                                                             DateTime.UtcNow.ToString("dd-MM-yyyyThh:mm:ss.ffff"));

                if (NativeEnabled && mqttClient != null && mqttClient.IsConnected)
                {
                    string jsonString = JsonConvert.SerializeObject(vdts);
                    byte[] data       = Encoding.UTF8.GetBytes(jsonString);
                    await mqttClient.PublishAsync(QualityOfServiceLevelType.AtMostOnce, outputPiSystem,
                                                  "application/json", data);
                }

                if (AppInsightsEnabled)
                {
                    tclient?.TrackEvent(name, vdts.GetEventProperties(), vdts.GetEventMetrics());
                }
            }
        }
Example #5
0
        public async Task PublishInput(MbapHeader header)
        {
            if (!NativeEnabled && !AppInsightsEnabled)
            {
                return;
            }

            DiagnosticsEvent telem = new DiagnosticsEvent(name, header.UnitId, header.TransactionId, DateTime.UtcNow.ToString("dd-MM-yyyyThh:mm:ss.ffff"));

            cache.Add(header.TransactionId.ToString(), DateTime.Now.Ticks, 20);

            if (NativeEnabled && mqttClient != null && mqttClient.IsConnected)
            {
                string jsonString = JsonConvert.SerializeObject(telem);
                byte[] msg        = Encoding.UTF8.GetBytes(jsonString);
                await mqttClient.PublishAsync(SkunkLab.Protocols.Mqtt.QualityOfServiceLevelType.AtMostOnce, outputPiSystem, "application/json", msg);
            }

            if (AppInsightsEnabled)
            {
                tclient?.TrackEvent(name, telem.GetEventProperties(), telem.GetEventMetrics());
            }
        }
Example #6
0
        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.");
            }
        }
Example #7
0
        public async Task SendAsync(byte[] message)
        {
            if (client == null || !client.IsConnected)
            {
                logger?.LogWarning("Module channel client is unavailable to send.");
                return;
            }

            try
            {
                MbapHeader header   = MbapHeader.Decode(message);
                string     pisystem = UriGenerator.GetRtuPiSystem(hostname, virtualRtuId, deviceId, header.UnitId, false);
                await client.PublishAsync(QualityOfServiceLevelType.AtMostOnce, pisystem, "application/json", message);

                await diag?.PublishOutput(header);

                logger?.LogDebug("Published message on module channel");
            }
            catch (Exception ex)
            {
                logger?.LogError(ex, "Fault sending on module channel.");
            }
        }
 public async Task SendRtuOutputAsync(byte[] message)
 {
     await pclient.PublishAsync(QualityOfServiceLevelType.AtLeastOnce, config.RtuOutputPiSsytem, Constants.CONTENT_TYPE, message);
 }
 public async Task SendAsync(string pisystem, string contentType, byte[] message)
 {
     await client.PublishAsync(QualityOfServiceLevelType.AtMostOnce, pisystem, contentType, message);
 }