Пример #1
0
        /// <summary>
        /// Listen to the CAN Bus (via TCP) and generate MQTT Message if there is an update
        /// </summary>
        /// <param name="canServer"></param>
        /// <param name="canPort"></param>
        /// <returns></returns>
        public async Task ConnectTcpCanBus(string canServer, int canPort)
        {
            try
            {
                //Create TCP Client for connection to canlogserver (=cls)
                TcpClient clsClient = null;
                while (clsClient == null || !clsClient.Connected)
                {
                    try
                    {
                        clsClient = new TcpClient(canServer, canPort);
                    }
                    catch (Exception ea)
                    {
                        Console.WriteLine("FAILED TO CONNECT TO CANLOGSERVER {1}. {0}. Retry...", ea.Message, canServer);
                    }
                    await Task.Delay(TimeSpan.FromSeconds(5));
                }

                Console.WriteLine("CONNECTED TO CANLOGSERVER {0} ON PORT {1}", canServer, canPort);

                //Create TCP Stream to read the CAN Bus Data
                NetworkStream stream       = clsClient.GetStream();
                byte[]        data         = new Byte[46];
                String        responseData = String.Empty;
                int           bytes        = stream.Read(data, 0, data.Length);
                var           previousData = "";

                //Infinite Loop
                while (bytes > 0)
                {
                    //Get the string from the received bytes. The string contains "(1561746016.537099) slcan0 180#D03CFA01120B00"
                    responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);

                    //Split by new line. canlogserver sends a line break after each CAN frame
                    foreach (var aData in responseData.Split('\n'))
                    {
                        //If there is nothing, ignore
                        if (aData.Length == 0)
                        {
                            continue;
                        }

                        //Each CAN frame is 45 characters and should start with a (. If not 45 chars, it is the first part of the frame received before.
                        if (aData.Length != 45 && aData.StartsWith("("))
                        {
                            //Store the data for next received packets to combine it.
                            previousData = aData;
                        }
                        else
                        {
                            //Create the CAN frame
                            var canFrame = new CanFrame
                            {
                                RawFrame = aData
                            };

                            //If the lenght is not 45 charactes and not starts with (, it is the second part of the frame stored above. Combine it and clear cache.
                            if (aData.Length != 45 && !aData.StartsWith("("))
                            {
                                canFrame.RawFrame = previousData + aData;
                                previousData      = "";
                            }

                            Console.WriteLine("Received CAN Frame: {0}", canFrame.RawFrame);

                            //If forwarding is disabled for this type of frame, ignore it.
                            if (canFrame.CanFrameType == "0" && !_CanForwardWrite ||
                                canFrame.CanFrameType == "1" && !_CanForwardRead ||
                                canFrame.CanFrameType == "2" && !_CanForwardResponse)
                            {
                                continue;
                            }

                            //Sent the CAN frame via MQTT
                            await SendMQTT(canFrame);
                        }
                    }
                    //Reset byte counter
                    bytes = 0;

                    //Get next packages from canlogserver
                    bytes = stream.Read(data, 0, data.Length);
                }
                //Close the TCP Stream
                clsClient.Close();

                Console.WriteLine("Disconnected from canServer {0} Port {1}", canServer, canPort);
            }
            catch (Exception ea)
            {
                Console.WriteLine("Error while reading CanBus Server. {0}", ea);
            }
            finally
            {
                //Reconnect to the canlogserver but do not wait for this here to avoid infinite loops
                _ = ConnectTcpCanBus(canServer, canPort); //Reconnect
            }
        }
Пример #2
0
        /// <summary>
        /// Sends a CAN-Message as a MQTT message
        /// </summary>
        /// <param name="canMsg"></param>
        /// <returns></returns>
        public async Task SendMQTT(CanFrame canMsg)
        {
            try
            {
                //Check if there is payload
                if (canMsg.RawFrame.Trim().Length == 0)
                {
                    return;
                }

                //Use Translator (if selected)
                if (!string.IsNullOrEmpty(_CanTranslator))
                {
                    //choose the translator to use and translate the message if translator exists
                    switch (_CanTranslator)
                    {
                    case "StiebelEltron":
                        var translator = new Translator.StiebelEltron.StiebelEltron();
                        canMsg = translator.Translate(canMsg, _NoUnits);
                        break;
                    }
                }

                //Verify connection to MQTT Broker is established
                while (!_MqttClient.IsConnected)
                {
                    Console.WriteLine("UNHANDLED DISCONNECT FROM MQTT BROKER");
                    while (!_MqttClient.IsConnected)
                    {
                        await Task.Delay(TimeSpan.FromSeconds(5));

                        try
                        {
                            await _MqttClient.ConnectAsync(_MqttClientOptions);

                            Console.WriteLine("CONNECTED TO MQTT BROKER");
                        }
                        catch
                        {
                            Console.WriteLine("RECONNECTING TO MQTT BROKER FAILED. Retrying...");
                        }
                    }
                }

                //Logoutput with or without tranlated MQTT message
                if (string.IsNullOrEmpty(canMsg.MqttValue))
                {
                    Console.WriteLine("Sending MQTT Message: {0} and Topic {1}", canMsg.PayloadFull.Trim(), _MqttTopic);
                }
                else
                {
                    Console.WriteLine("Sending MQTT Message: {0} and Topic {1}{2}", canMsg.MqttValue, _MqttTopic, canMsg.MqttTopicExtention);
                }

                //Create MQTT Message
                var message = new MqttApplicationMessageBuilder()
                              .WithTopic(_MqttTopic + canMsg.MqttTopicExtention)
                              .WithPayload(string.IsNullOrEmpty(canMsg.MqttValue) ? canMsg.PayloadFull : canMsg.MqttValue)
                              .WithExactlyOnceQoS()
                              .WithRetainFlag()
                              .Build();

                //Publish MQTT Message
                await _MqttClient.PublishAsync(message);
            }
            catch (Exception ea)
            {
                Console.WriteLine("ERROR while sending MQTT message. {0}", ea.ToString());
            }
        }