0

.NET で開発された検査情報システム (LIS) と、Beckman Coulter Inc. によって作成された検査装置システムの API である Remisol 2000 Data Manager との間のインターフェースを開発する必要があります。 LISに。

開始できるウェブ上のリソースはありますか? Socket を開く必要があると思いますが、ドキュメントには、Synchron LX20、Synchron CX7、ASTM、ASTMH2、LIS Gen.S などのプロトコルのメッセージ構造のみが記載されています。

それらはすべてシリアル プロトコルを使用します。

using System;
using System.IO.Ports;
using System.Threading;

public class ClientToBeckmanDL2000
{
    static bool _continue;
    static SerialPort _serialPort;
    static bool keepRetrying = true;

    public static void Main()
    {

        CreateNewSerialPortAndOpenIt();

        SendAndReceiveMessagesInALoop();

        CloseTheSerialPort();
    }

    private static void CloseTheSerialPort()
    {
        _serialPort.Close();
    }

    private static void SendAndReceiveMessagesInALoop()
    {
        StringComparer stringComparer = StringComparer.OrdinalIgnoreCase;
        string outputMessage, inputMessage;
        _continue = true;
        DateTime startTime, endTime;
        TimeSpan diffInSeconds;
        int retryCounter = 0;


        Console.WriteLine("Type QUIT to exit");

        try
        {
            while (_continue)
            {
                outputMessage = Console.ReadLine();

                _serialPort.WriteLine(
                        String.Format("{0}", outputMessage));

                if (outputMessage.Equals("ENQ") || outputMessage.Equals("<ENQ>") ||
                    outputMessage.Equals("EOT SOH") || outputMessage.Equals("<EOT> <SOH>") ||
                    outputMessage.Equals("<EOT><SOH>"))
                {
                    while (keepRetrying.Equals(true))
                    {
                        startTime = DateTime.Now;
                        inputMessage = string.Empty;

                        inputMessage = GetResponseFromServerInALoop();



                        endTime = DateTime.Now;
                        diffInSeconds = endTime - startTime;

                        // if the time for response crosses 15 seconds keep retrying
                        if (diffInSeconds.Seconds > 15)
                        {
                            retryCounter++;
                            keepRetrying = true;
                            Console.WriteLine("Retrying..." + retryCounter.ToString());
                            Console.WriteLine(" ");
                            if (retryCounter > 7)
                            {
                                keepRetrying = false;
                                Console.WriteLine("Tried more than 7 times . Line down. Please try again later...");
                                break;
                            }


                        }
                        else
                            if (inputMessage.ToString().Length > 0 && (inputMessage.Equals("STX")))
                            {
                                Console.WriteLine("Response is " + inputMessage.ToString() + " The Remisol server is bidding for line. Try to send your message later ... ");
                                keepRetrying = false;
                            }
                            else
                                if (inputMessage.ToString().Length > 0 && (!inputMessage.Equals("ACK") && !inputMessage.Equals("NAK") && !inputMessage.Equals("STX")))
                                {
                                    Console.WriteLine("Response is " + inputMessage.ToString() + " It should be ACK or NAK or STX. Try again ... ");
                                    keepRetrying = false;
                                }
                                else
                                    if (inputMessage.ToString().Length > 0 && (inputMessage.Equals("NAK")))
                                    {
                                        Console.WriteLine("Response is " + inputMessage.ToString() + " It should be ACK. Try again ... ");
                                        keepRetrying = false;
                                    }
                                    else
                                    {
                                        Console.WriteLine("Please key in [00,800,01]97<CR><LF> to check Remisol..");
                                        keepRetrying = false;
                                    }
                        if (keepRetrying.Equals(true))
                        {
                            _serialPort.WriteLine(String.Format("{0}", outputMessage));
                        }
                    }
                }
                else
                    if (outputMessage.Equals("[00,800,01]97<CR><LF>"))
                    {
                        do
                        {
                            inputMessage = _serialPort.ReadLine();
                            System.Threading.Thread.Sleep(1000);
                            keepRetrying = false;
                            Console.WriteLine(inputMessage);

                        } while (inputMessage.Equals(null));

                        Console.WriteLine("Response is " + inputMessage.ToString());
                    }
                if (stringComparer.Equals("quit", outputMessage))
                {
                    _continue = false;
                }

            }
        }
        catch (Exception) { }
    }

    private static string GetResponseFromServerInALoop()
    {
        string inputMessage = string.Empty;


        do {
            inputMessage = _serialPort.ReadLine();

            System.Threading.Thread.Sleep(10);
            keepRetrying = false;
            Console.WriteLine(inputMessage);

        }
        while (inputMessage.Equals(string.Empty));

        return inputMessage;
    }

    private static void CreateNewSerialPortAndOpenIt()
    {
        _serialPort = new SerialPort();

        // Allow the user to set the appropriate properties.
        _serialPort.PortName = SetPortName(_serialPort.PortName);
        _serialPort.BaudRate = SetPortBaudRate(_serialPort.BaudRate);
        _serialPort.Parity = SetPortParity(_serialPort.Parity);
        _serialPort.DataBits = SetPortDataBits(_serialPort.DataBits);
        _serialPort.StopBits = SetPortStopBits(_serialPort.StopBits);
        _serialPort.Handshake = SetPortHandshake(_serialPort.Handshake);

        // Set the read/write timeouts
        //_serialPort.ReadTimeout = 0; -- this is being commented since this testing program needs to run for long time without timeouts. The default is anyway 0 which is infinite timeouts
        //_serialPort.WriteTimeout = 500000; -- this too is being commented out since it needs to run infinitely for test

        _serialPort.Open();
    }


    public static string SetPortName(string defaultPortName)
    {
        string portName;

        Console.WriteLine("Available Ports:");
        foreach (string s in SerialPort.GetPortNames())
        {
            Console.WriteLine("   {0}", s);
        }

        Console.Write("COM port({0}): ", defaultPortName);
        portName = Console.ReadLine();

        if (portName == "")
        {
            portName = defaultPortName;
        }
        return portName;
    }

    public static int SetPortBaudRate(int defaultPortBaudRate)
    {
        string baudRate;

        Console.Write("Baud Rate({0}): ", defaultPortBaudRate);
        baudRate = Console.ReadLine();

        if (baudRate == "")
        {
            baudRate = defaultPortBaudRate.ToString();
        }

        return int.Parse(baudRate);
    }

    public static Parity SetPortParity(Parity defaultPortParity)
    {
        string parity;

        Console.WriteLine("Available Parity options:");
        foreach (string s in Enum.GetNames(typeof(Parity)))
        {
            Console.WriteLine("   {0}", s);
        }

        Console.Write("Parity({0}):", defaultPortParity.ToString());
        parity = Console.ReadLine();

        if (parity == "")
        {
            parity = defaultPortParity.ToString();
        }

        return (Parity)Enum.Parse(typeof(Parity), parity);
    }

    public static int SetPortDataBits(int defaultPortDataBits)
    {
        string dataBits;

        Console.Write("Data Bits({0}): ", defaultPortDataBits);
        dataBits = Console.ReadLine();

        if (dataBits == "")
        {
            dataBits = defaultPortDataBits.ToString();
        }

        return int.Parse(dataBits);
    }

    public static StopBits SetPortStopBits(StopBits defaultPortStopBits)
    {
        string stopBits;

        Console.WriteLine("Available Stop Bits options:");
        foreach (string s in Enum.GetNames(typeof(StopBits)))
        {
            Console.WriteLine("   {0}", s);
        }

        Console.Write("Stop Bits({0}):", defaultPortStopBits.ToString());
        stopBits = Console.ReadLine();

        if (stopBits == "")
        {
            stopBits = defaultPortStopBits.ToString();
        }

        return (StopBits)Enum.Parse(typeof(StopBits), stopBits);
    }

    public static Handshake SetPortHandshake(Handshake defaultPortHandshake)
    {
        string handshake;

        Console.WriteLine("Available Handshake options:");
        foreach (string s in Enum.GetNames(typeof(Handshake)))
        {
            Console.WriteLine("   {0}", s);
        }

        Console.Write("Stop Bits({0}):", defaultPortHandshake.ToString());
        handshake = Console.ReadLine();

        if (handshake == "")
        {
            handshake = defaultPortHandshake.ToString();
        }

        return (Handshake)Enum.Parse(typeof(Handshake), handshake);
    }
}
4

1 に答える 1

1

私は、LIMS システムを実験器具 (私の場合はサーモサイクラー) に同様に接続しました。

あなたが言及した特定の機器については知りませんが、多くのラボ機器は何らかの形のシリアル インターフェイスを使用しています。物理層は、rs232 (計測器がベンチにスタンドアロンで存在することを意図している場合) または rs485 (「デイジーチェーン」構成で一緒に連結する必要がある複数の計測器がある場合) のいずれかです。プロトコル レベルは、さまざまな単純なメッセージ/応答パターンにすることができます。これらのいくつかは実際に標準 (ASTM 1394) であり、その他はオペコード、データ、およびチェックサムを含む単純なバイト ブロックで構成される「自作」のジョブです。いずれにせよ、使用できる API ライブラリがない場合は、優れたドキュメントが必要になります。このようなものを入手するには、電話をかけなければならない場合があります。インターネット上で常に入手できるとは限りません。

よくある問題の 1 つは、LIMS システムを実行するサーバーがどこかのデータセンターにあり、機器がラボにあることです。さらに悪いことに、サーバーにはシリアル ポートがなく、計測器にはイーサネットがありません。

これを回避するには、「シリアル ターミナル サーバー」または「シリアル デバイス サーバー」を使用します (例:リンク)。これらは、イーサネット トラフィックを受け取り、それを 1 つまたは複数のシリアル ポート (ポートは rs232、rs422、または rs485 として構成できます) にルーティングする小さな金属製のボックスです。サーバーには、リモート ターミナル サーバー上のこれらのポートを実際のポートとしてサーバー アプリケーションに表示させるドライバーをインストールします。または、特定の TCP/IP ソケットとの間でデータを特定のシリアル ポートにルーティングすることもできます。

それが機能するようになれば、多くの時間を節約できる非常にやりがいのあるプロジェクトです。幸運を!

于 2009-10-27T13:17:21.923 に答える