2009-06-10 66 views
0

我需要開發一個在.NET中開發的實驗室信息系統(LIS)與Remisol 2000數據管理器之間的接口,該管理器是Beckman製造的實驗室儀器系統的API Coulter Inc.這個想法是將測試結果以編程方式提取到LIS中。Remisol 2000 Data Manager的實驗室信息系統接口

網絡上有沒有資源可以給我一個開始?我認爲我需要打開一個套接字,但文檔只提到協議的消息結構,如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); 
    } 
} 
+0

定義上述每種協議的每種類型,它們是串行的,基於tcp-ip,x25也許。首先定義。 – 2009-10-23 16:58:15

+0

那麼Synchron CX7有一個串行接口。 – 2009-10-23 17:00:21

回答

1

我已經做了類似的接口的LIMS系統,實驗室儀器(在我的情況,thermocyclers)。

我不知道你提到的具體儀器,但許多實驗儀器使用某種形式的串行接口。物理層可以是rs232(如果儀器打算獨立存在於工作臺上),也可以是rs485(如果有多個儀器需要以「菊花鏈」配置組合在一起)。協議級別可以是各種簡單的消息/響應模式。其中一些實際上是標準(ASTM 1394),另外一些是「自制」作業,由簡單的字節塊組成,其中包含操作碼,數據和校驗和。不管它是什麼,如果你沒有可用的API庫,你需要很好的文檔。你可能不得不打電話來獲取這些東西,它並不總是在互聯網上。

您將遇到的問題之一是運行LIMS系統的服務器通常位於某個數據中心,而您的儀器位於實驗室中。更糟糕的是,服務器沒有串口,儀器沒有以太網。

爲了解決這個問題,您需要使用「串行終端服務器」或「串行設備服務器」(例如... link)。這些小金屬盒採用以太網通信並將其路由到一個或多個串行端口(端口可以配置爲rs232或rs422或rs485)。在服務器上安裝驅動程序,使遠程終端服務器上的這些端口顯示爲服務器應用程序的實際端口。或者,您也可以選擇將數據從特定TCP/IP套接字路由到特定串行端口。

如果你得到它的工作,這是一個非常好的獎勵項目,節省了大量的時間。祝你好運!