Index: .gitignore
===================================================================
--- .gitignore	(revision aabd3137f27cff940ddc24482bd22f9afd50e46d)
+++ .gitignore	(revision 17a73f39cfa90ee2c8ecb1880888ab3b39acf893)
@@ -296,2 +296,3 @@
 #Ipython Notebook
 .ipynb_checkpoints
+/nbproject/
Index: pom.xml
===================================================================
--- pom.xml	(revision 83b966a9241bba2d3e13e91dc6635c00389b60b8)
+++ pom.xml	(revision 17a73f39cfa90ee2c8ecb1880888ab3b39acf893)
@@ -156,5 +156,17 @@
     
     
-    <dependencies>        
+    <dependencies>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.12</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest-core</artifactId>
+            <version>1.3</version>
+            <scope>test</scope>
+        </dependency>
         <dependency>
             <groupId>javax</groupId>
Index: src/main/java/cn/ac/csns/microscope/managed/BL18StatusController.java
===================================================================
--- src/main/java/cn/ac/csns/microscope/managed/BL18StatusController.java	(revision 17a73f39cfa90ee2c8ecb1880888ab3b39acf893)
+++ src/main/java/cn/ac/csns/microscope/managed/BL18StatusController.java	(revision 17a73f39cfa90ee2c8ecb1880888ab3b39acf893)
@@ -0,0 +1,98 @@
+package cn.ac.csns.microscope.managed;
+
+import cn.ac.csns.microscope.StatusMapper;
+import cn.ac.csns.microscope.ejb.BL01StatusFacade;
+import cn.ac.csns.microscope.entity.BL01Status;
+import cn.ac.csns.microscope.exception.TransferException;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.annotation.PostConstruct;
+import javax.ejb.EJB;
+import javax.faces.application.FacesMessage;
+import javax.faces.context.FacesContext;
+import javax.inject.Named;
+import javax.faces.view.ViewScoped;
+
+/**
+ *
+ * @author tangm <a href="mailto:tangm@ihep.ac.cn">Tang Ming</a>
+ */
+@Named
+@ViewScoped
+public class BL01StatusController implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+    private List<BL01Status> status;
+    private List<BL01Status> filteredStatus;
+    private Calendar updateTime;
+    private boolean updating;
+    private int updateInterval = 10;
+
+    @EJB
+    BL01StatusFacade facade;
+
+    /**
+     * Creates a new instance of BL01Controller
+     */
+    public BL01StatusController() {
+        status = new ArrayList<>();
+    }
+
+    @PostConstruct
+    private void init() {
+        updateStatus();
+    }
+
+    synchronized public void updateStatus() {
+        if (updating) {
+            return;
+        }
+        updating = true;
+        try {
+            status = facade.findAll();
+            status.sort((p1, p2) -> p2.getRun().compareToIgnoreCase(p1.getRun()));
+            updateTime = Calendar.getInstance();
+        } catch (TransferException ex) {
+            Logger.getLogger(BL01StatusController.class.getName()).log(Level.SEVERE, ex.getLocalizedMessage(), ex);
+            FacesContext.getCurrentInstance()
+                    .addMessage(null,
+                            new FacesMessage(FacesMessage.SEVERITY_ERROR,
+                                    ex.getLocalizedMessage(),
+                                    ex.getLocalizedMessage()));
+        }
+        updating = false;
+    }
+
+    public String getStringStatus(Integer statusId) {
+        return StatusMapper.getStringStatus(statusId);
+    }
+
+    public List<BL01Status> getStatus() {
+        return status;
+    }
+
+    public List<BL01Status> getFilteredStatus() {
+        return filteredStatus;
+    }
+
+    public void setFilteredStatus(List<BL01Status> filteredStatus) {
+        this.filteredStatus = filteredStatus;
+    }
+
+    public Calendar getUpdateTime() {
+        return updateTime;
+    }
+
+    public int getUpdateInterval() {
+        return updateInterval;
+    }
+
+    public void setUpdateInterval(int updateInterval) {
+        this.updateInterval = updateInterval;
+    }
+
+}
Index: src/main/webapp/bl01status.xhtml
===================================================================
--- src/main/webapp/bl01status.xhtml	(revision 2ddb327f5499cf9842411d49aa16f20c47ff5bac)
+++ src/main/webapp/bl01status.xhtml	(revision 17a73f39cfa90ee2c8ecb1880888ab3b39acf893)
@@ -13,5 +13,9 @@
         </f:facet>
     </h:head>
-    <h:body>       
+    <h:body>
+        <p:outputPanel style="text-align: center">
+            <h1>SANS Data Transfer Status</h1>
+        </p:outputPanel>
+        
         <p:messages id="global_msg" globalOnly="true" autoUpdate="true"/>
 
Index: src/main/webapp/bl18status.xhtml
===================================================================
--- src/main/webapp/bl18status.xhtml	(revision 17a73f39cfa90ee2c8ecb1880888ab3b39acf893)
+++ src/main/webapp/bl18status.xhtml	(revision 17a73f39cfa90ee2c8ecb1880888ab3b39acf893)
@@ -0,0 +1,100 @@
+<?xml version='1.0' encoding='UTF-8' ?>
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml"
+      xmlns:h="http://xmlns.jcp.org/jsf/html"
+      xmlns:p="http://primefaces.org/ui"
+      xmlns:f="http://xmlns.jcp.org/jsf/core">
+    <h:head>
+        <f:facet name="first">
+            <meta charset="UTF-8" />
+            <meta name="viewport" content="width=device-width, initial-scale=1" />
+            <meta http-equiv="X-UA-Compatible" content="IE=edge" /> 
+            <title>GPPD Transfer Status</title>
+        </f:facet>
+    </h:head>
+    <h:body>
+        <p:outputPanel style="text-align: center">
+            <h1>GPPD Data Transfer Status</h1>
+        </p:outputPanel>
+        
+        <p:messages id="global_msg" globalOnly="true" autoUpdate="true"/>
+
+        <h:form>
+            <p:dataTable id="bl18_transfer_status"
+                         value="#{bL18StatusController.status}"
+                         var="current"
+                         filteredValue="#{bL18StatusController.filteredStatus}"                         
+                         paginator="true" reflow="true" rows="30"
+                         rowsPerPageTemplate="10,30,50,100"
+                         resizableColumns="true" liveResize="true"
+                         draggableColumns="true" stickyHeader="true"
+                         style="text-align: center">
+                <f:facet name="header">
+                    <h:outputText value="Status of Runs (total: #{bL18StatusController.status.size()})"/><br/>
+                    <h:outputText value="Updated at: " style="font-size: small"/>
+                    <h:outputText value="#{bL18StatusController.updateTime.time}"
+                                  style="font-size: small">
+                        <f:convertDateTime pattern="YYYY-MM-dd HH:mm:ss"
+                                           timeZone="#{bL18StatusController.updateTime.timeZone}" />                
+                    </h:outputText><p/>
+                    <h:outputText value="Update Interval(min): "
+                                  style="font-size: small"/>
+                    <p:selectOneMenu value="#{bL18StatusController.updateInterval}">
+                        <f:selectItem itemLabel="1" itemValue="1"/>
+                        <f:selectItem itemLabel="5" itemValue="5"/>
+                        <f:selectItem itemLabel="10" itemValue="10"/>
+                        <f:selectItem itemLabel="30" itemValue="30"/>
+                        <f:selectItem itemLabel="60" itemValue="60"/>                        
+                        <p:ajax update="@form" process="@this"/>
+                    </p:selectOneMenu>
+                </f:facet>
+                <p:column headerText="RUN"
+                          filterBy="#{current.run}" filterMatchMode="contains">
+                    <h:outputText value="#{current.run}"/>
+                </p:column>
+                <p:column headerText="Control" filterBy="#{current.ctrl}">
+                    <h:outputText rendered="#{current.ctrl}" class="fa fa-check"/>
+                </p:column>
+                <p:column headerText="Detector" filterBy="#{current.daq}">
+                    <h:outputText rendered="#{current.daq}" class="fa fa-check"/>
+                </p:column>
+                <p:column headerText="Monitor1 Histogram" filterBy="#{current.monHis1}">
+                    <h:outputText rendered="#{current.monHis1}" class="fa fa-check"/>
+                </p:column>
+                <p:column headerText="Monitor1 Event" filterBy="#{current.monEvt1}">
+                    <h:outputText rendered="#{current.monEvt1}" class="fa fa-check"/>
+                </p:column>
+                <p:column headerText="Monitor2 Histogram" filterBy="#{current.monHis2}">
+                    <h:outputText rendered="#{current.monHis2}" class="fa fa-check"/>
+                </p:column>
+                <p:column headerText="Monitor2 Event" filterBy="#{current.monEvt2}">
+                    <h:outputText rendered="#{current.monEvt2}" class="fa fa-check"/>
+                </p:column>
+                <p:column headerText="Monitor3 Histogram" filterBy="#{current.monHis3}">
+                    <h:outputText rendered="#{current.monHis3}" class="fa fa-check"/>
+                </p:column>
+                <p:column headerText="Monitor3 Event" filterBy="#{current.monEvt3}">
+                    <h:outputText rendered="#{current.monEvt3}" class="fa fa-check"/>
+                </p:column>
+                <p:column headerText="NeXus" filterBy="#{current.nexus}">
+                    <h:outputText rendered="#{current.nexus}" class="fa fa-check"/>
+                </p:column>
+                <p:column headerText="Begin"
+                          filterBy="#{current.begin}" filterMatchMode="contains">
+                    <h:outputText value="#{current.begin}"/>
+                </p:column>
+                <p:column headerText="End"
+                          filterBy="#{current.end}" filterMatchMode="contains">
+                    <h:outputText value="#{current.end}"/>
+                </p:column>
+                <p:column headerText="Status" filterBy="#{current.stat}">
+                    <h:outputText value="#{bL18StatusController.getStringStatus(current.stat)}"/>
+                </p:column>
+            </p:dataTable>            
+            <p:poll interval="#{bL18StatusController.updateInterval * 60}"
+                    listener="#{bL18StatusController.updateStatus}"
+                    update="bl18_transfer_status"/>
+        </h:form>
+    </h:body>
+</html>
+
Index: src/main/webapp/index.xhtml
===================================================================
--- src/main/webapp/index.xhtml	(revision 2ddb327f5499cf9842411d49aa16f20c47ff5bac)
+++ src/main/webapp/index.xhtml	(revision 17a73f39cfa90ee2c8ecb1880888ab3b39acf893)
@@ -19,8 +19,7 @@
                     Transfer Service Status Viewer
                 </f:facet>
-                <p:commandLink value="SANS"
-                               action="bl01status?faces-redirect=true"/>
+                <h:outputLink value="bl01status.xhtml">SANS</h:outputLink>
                 <p:commandLink value="MR"/>
-                <p:commandLink value="GPPD"/>
+                <h:outputLink value="bl18status.xhtml">GPPD</h:outputLink>
             </p:panelGrid> 
         </h:form>
Index: src/test/java/cn/ac/csns/microscope/StatusMapperTest.java
===================================================================
--- src/test/java/cn/ac/csns/microscope/StatusMapperTest.java	(revision 17a73f39cfa90ee2c8ecb1880888ab3b39acf893)
+++ src/test/java/cn/ac/csns/microscope/StatusMapperTest.java	(revision 17a73f39cfa90ee2c8ecb1880888ab3b39acf893)
@@ -0,0 +1,23 @@
+package cn.ac.csns.microscope;
+
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ * @author tangm <a href="mailto:tangm@ihep.ac.cn">Tang Ming</a>
+ */
+public class StatusMapperTest {
+    
+    public StatusMapperTest() {
+    }
+
+    @Test
+    public void testGetStringStatus() {
+        assertEquals("New", StatusMapper.getStringStatus(0));
+        assertEquals("Raw Backuped", StatusMapper.getStringStatus(6));
+        assertEquals("Unknown", StatusMapper.getStringStatus(-1));
+        assertEquals("Unknown", StatusMapper.getStringStatus(7));
+    }
+    
+}
