实验室信息系统与Remisol 2000数据管理器的接口

时间:2009-06-10 15:19:21

标签: .net integration

我需要开发一个用.NET开发的实验室信息系统(LIS)和Remisol 2000数据管理器之间的接口,这是一个由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);
    }
}

1 个答案:

答案 0 :(得分:1)

我已经为LIMS系统与实验室仪器进行了类似的接口(在我的例子中,thermocyclers)。

我不知道您提到的具体仪器,但许多实验室仪器使用某种形式的串行接口。物理层可以是rs232(如果仪器旨在独立存在于工作台上),也可以是rs485(如果有多个仪器需要以“菊花链”配置组合在一起)。协议级别可以是各种各样的简单消息/响应模式。其中一些实际上是标准(ASTM 1394),其他是“自制”作业,包括带有操作码,数据和校验和的简单字节块。无论是什么,如果您没有可以使用的API库,您将需要良好的文档。你可能不得不打电话来获取这些东西,但并不总是可以上网。

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

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

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