0

我需要在 .NET 中开发的实验室信息系统 (LIS) 和 Remisol 2000 Data Manager 之间开发一个接口,Remisol 2000 Data Manager 是 Beckman Coulter Inc. 制造的实验室仪器系统的 API。这个想法是以编程方式获取测试结果进入 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 库,您将需要好的文档。你可能需要打电话才能得到这些东西,它并不总是在互联网上可用。

您将遇到的问题之一是运行 LIMS 系统的服务器通常位于某个数据中心中,而您的仪器位于实验室中。更糟糕的是,服务器没有串口,仪器也没有以太网。

为了解决这个问题,您需要使用“串行终端服务器”或“串行设备服务器”(例如...链接)。这些是小型金属盒,可以接收以太网流量并将其路由到一个或多个串行端口(端口可以配置为 rs232 或 rs422 或 rs485)。在服务器上,您安装一个驱动程序,使远程终端服务器上的这些端口显示为服务器应用程序的实际端口。或者,您还可以选择将数据路由到特定 TCP/IP 套接字或从特定串行端口路由数据。

如果你让它工作,这是一个非常整洁的奖励项目,可以节省大量时间。祝你好运!

于 2009-10-27T13:17:21.923 回答