/// <summary>
        /// Initialization of the serial port based on the port configuration
        /// </summary>
        private static ISerialDevice InitSerialPort(PortConfig portConfig)
        {
            if (portConfig.Device.Substring(0, 3) == "COM" ||
                portConfig.Device.Substring(0, 8) == "/dev/tty" ||
                portConfig.Device.Substring(0, 11) == "/dev/rfcomm")
            {
                try
                {
                    Log.Information($"Opening port '{portConfig.Device}' ({portConfig.BaudRate}, {portConfig.DataBits}, StopBitsEnum: {portConfig.StopBitsEnum}, ParityEnum: {portConfig.ParityEnum}) for '{portConfig.Direction}'");

                    var serialPort = OpenSerial(portConfig.Device,
                                                portConfig.BaudRate,
                                                portConfig.ParityEnum,
                                                portConfig.DataBits,
                                                portConfig.StopBitsEnum,
                                                portConfig.Direction);

                    if (serialPort == null)
                    {
                        Log.Debug("For some reason, serial port creation failed.");
                    }

                    return(serialPort);
                }
                catch (Exception ex)
                {
                    Log.Error($"{ex.Message}");

                    Log.Debug($"Inner Exception InitSerialPort: {ex.InnerException?.ToString()}");
                }
            }

            return(null);
        }
        /// <summary>
        /// Read the byte[] response from a serial port
        /// </summary>
        private static byte[] ReadResponse(ISerialDevice serialPort, PortConfig portConfig)
        {
//            Log.Verbose("Read next line...");

            int bytesRead = 0;

            int delimiterIndex = 0;

            var temp = new List <byte>();

            var buf = new byte[1];

            //read until end delimiter is reached eg. \r\n in 12345\r\n67890
            while (serialPort != null && _run && bytesRead < 1024)
            {
                var i = serialPort.Read(buf, 0, 1);

                if (i < 1)
                {
                    continue;
                }

                var str = System.Text.Encoding.Default.GetString(buf);

                temp.Add(buf[0]);

                if (str[0] != portConfig.Delimiter[delimiterIndex])
                {
                    delimiterIndex = 0;
                }
                else
                {
                    delimiterIndex++;
                    if (delimiterIndex == portConfig.Delimiter.Length)
                    {
                        temp.RemoveRange(temp.Count - portConfig.Delimiter.Length,
                                         portConfig.Delimiter.Length);
                        break;
                    }
                }

                bytesRead++;
            }

            if (bytesRead == _maxBytesToRead)
            {
                Log.Warning($"Delimiter '{ShowControlCharacters(portConfig.Delimiter)}' not found in last {_maxBytesToRead} bytes read.");
                temp.Clear();
            }

            if (!_run)
            {
                Log.Debug("Shutdown reading");
                temp.Clear();
            }

            if (serialPort == null)
            {
                Log.Debug("No port available anymore");
                temp.Clear();
            }

            return(temp.ToArray());
        }
        /// <summary>
        /// Execution method for a 'Read' or 'Write' task per port.
        /// </summary>
        private static async Task SerialTaskBody(string port, PortConfig portConfig, ModuleClient client, SerialMessageBroadcaster serialMessageBroadcaster)
        {
            try
            {
                Log.Debug($"Creating port");

                // create serial port
                var serialPort = InitSerialPort(portConfig);

                if (serialPort == null)
                {
                    Log.Debug($"Task for {port} aborted.");
                    return;
                }

                Log.Debug($"Port '{port}' created");

                if (portConfig.Direction == "Read")
                {
                    Log.Debug($"Start read loop");

                    // Looping infinitely until desired properties are updated.
                    while (serialPort != null && _run)
                    {
                        var response = ReadResponse(serialPort, portConfig);

                        if (portConfig.IgnoreEmptyLines &&
                            response.Length == 0)
                        {
                            Log.Debug($"Ignore empty line");
                            continue;
                        }

                        var data = Encoding.UTF8.GetString(response);

                        if (portConfig.DelimiterInOutput)
                        {
                            if (portConfig.DelimiterAtStart)
                            {
                                data = portConfig.Delimiter + data;
                            }
                            else
                            {
                                data = data + portConfig.Delimiter;
                            }
                        }

                        Log.Debug($"Data read from '{portConfig.Device}': '{data}'");

                        var serialMessage = new SerialMessage
                        {
                            Data         = data,
                            Port         = port,
                            TimestampUtc = DateTime.UtcNow,
                        };

                        var jsonMessage = JsonConvert.SerializeObject(serialMessage);

                        Log.Debug($"Message out: '{jsonMessage}'");

                        var byteMessage = Encoding.UTF8.GetBytes(jsonMessage);

                        using (var pipeMessage = new Message(byteMessage))
                        {
                            pipeMessage.ContentType     = "application/json";
                            pipeMessage.ContentEncoding = "utf-8";

                            pipeMessage.Properties.Add("content-type", "application/edge-serial-json");

                            await client.SendEventAsync(port, pipeMessage);
                        }

                        Log.Debug($"Message sent to output: {port}");

                        // wait a certain interval
                        await Task.Delay(portConfig.SleepInterval);
                    }

                    Log.Debug($"Disposing port '{port}'");

                    // Ingest stopped. Tear down port
                    DisposeSerialPort(serialPort);

                    Log.Debug($"Disposed port '{port}'");
                }
                else if (portConfig.Direction == "Write")
                {
                    Log.Debug("Let's write to serial");

                    serialMessageBroadcaster.BroadcastEvent += (sender, se) =>
                    {
                        Log.Debug($"Executing BroadcastEvent for port '{se.Port}'");

                        if (se.Port == port)
                        {
                            Log.Debug($"BroadcastEvent has been picked up");

                            byte[] valueBytes     = se.Message;
                            byte[] delimiterBytes = Encoding.UTF8.GetBytes(portConfig.Delimiter);
                            byte[] totalBytes     = valueBytes.Concat(delimiterBytes).ToArray();

                            Log.Debug($"BroadcastEvent message converted");

                            if (serialPort != null && totalBytes.Length > 0)
                            {
                                serialPort.Write(totalBytes, 0, totalBytes.Length);
                                Log.Information($"Written to '{se.Port}': '{ShowControlCharacters(Encoding.UTF8.GetString(totalBytes))}'");
                            }
                            else
                            {
                                Log.Information($"Value not written to '{se.Port}', no port available or empty message");
                            }

                            Log.Debug($"BroadcastEvent message handled");
                        }
                    };

                    while (serialPort != null && _run)
                    {
                        await Task.Delay(portConfig.SleepInterval);
                    }
                    ;
                }

                Log.Debug($"Task for {port} ended.");
            }
            catch (Exception ex)
            {
                // if one task fails, we just shut it down

                Log.Error($"{ex.Message}");

                Log.Debug($"Inner Exception SerialTaskBody: {ex.InnerException?.ToString()}");
            }
        }
예제 #4
0
        public void Validate()
        {
            List <string> invalidConfigs = new List <string>();

            foreach (var config_pair in PortConfigs)
            {
                PortConfig portConfig = config_pair.Value;

                var key = config_pair.Key;

                if (portConfig == null)
                {
                    Console.WriteLine($"{key} configuration is null, remove from dictionary...");
                    invalidConfigs.Add(key);
                    continue;
                }

                if (string.IsNullOrEmpty(portConfig.Device))
                {
                    Console.WriteLine($"missing device for {key}");
                    invalidConfigs.Add(key);
                }

                if (string.IsNullOrEmpty(portConfig.Direction))
                {
                    portConfig.Direction = DefaultDirection;
                    Console.WriteLine($"Invalid direction for {key}. Set to default {DefaultDirection}");
                }

                if (portConfig.SleepInterval < 1)
                {
                    portConfig.SleepInterval = DefaultSleepInterval;
                    Console.WriteLine($"Invalid sleep interval for {key}. Set to default {DefaultSleepInterval}");
                }

                if (portConfig.BaudRate < 1)
                {
                    portConfig.BaudRate = DefaultBaudRate;
                    Console.WriteLine($"Invalid baudRate for {key}. Set to default {DefaultBaudRate}");
                }

                if (!string.IsNullOrEmpty(portConfig.Parity))
                {
                    switch (portConfig.Parity)
                    {
                    case "None":
                        portConfig.ParityEnum = Parity.None;
                        break;

                    case "Even":
                        portConfig.ParityEnum = Parity.Even;
                        break;

                    case "Odd":
                        portConfig.ParityEnum = Parity.Odd;
                        break;

                    case "Mark":
                        portConfig.ParityEnum = Parity.Mark;
                        break;

                    case "Space":
                        portConfig.ParityEnum = Parity.Space;
                        break;

                    default:
                        portConfig.Parity = DefaultParity;
                        Console.WriteLine($"Invalid parity '{portConfig.Parity}' for '{key}'. Set to default {DefaultParity}");
                        break;
                    }
                    ;
                }
                else
                {
                    portConfig.Parity = DefaultParity;
                    Console.WriteLine($"Missing parity for {key}. Set to default {DefaultParity}");
                }

                if (portConfig.DataBits < 1)
                {
                    portConfig.DataBits = DefaultDataBits;
                    Console.WriteLine($"Invalid databits for {key}. Set to default {DefaultDataBits}");
                }

                if (!string.IsNullOrEmpty(portConfig.StopBits))
                {
                    switch (portConfig.StopBits)
                    {
                    case "None":
                        portConfig.StopBitsEnum = StopBits.None;
                        break;

                    case "One":
                        portConfig.StopBitsEnum = StopBits.One;
                        break;

                    case "OnePointFive":
                        portConfig.StopBitsEnum = StopBits.OnePointFive;
                        break;

                    case "Two":
                        portConfig.StopBitsEnum = StopBits.Two;
                        break;

                    default:
                        portConfig.StopBits = DefaultStopBits;
                        Console.WriteLine($"Invalid stopbits '{portConfig.StopBits}' for '{key}'. Set to default {DefaultParity}");
                        break;
                    }
                    ;
                }
                else
                {
                    portConfig.StopBits = DefaultStopBits;
                    Console.WriteLine($"Missing stopBits for {key}. Set to default {DefaultStopBits}");
                }

                if (string.IsNullOrEmpty(portConfig.Delimiter))
                {
                    portConfig.Delimiter = DefaultDelimiter;
                    Console.WriteLine($"Missing delimiter for {key}. Set to defailt {DefaultDelimiter}");
                }
            }

            foreach (var invalidPort in invalidConfigs)
            {
                PortConfigs.Remove(invalidPort);
            }
        }