01.31 工廠自動化數據Shiny App展示

半導體封裝行業已經實現工廠自動化中,涉及到一些作業流程,也產生了很多的alarm及過站信息,需要做個dashboard看板,將報警和過站信息結合起來看。

利用R的shiny包可以很快的構架數據看板。代碼如下:

ui.R:

library(shiny)

library(shinydashboard)

library(DT)

library(ggplot2)

library(tidyr)

library(rCharts)

library(dplyr)

library(stringr)

library(plotly)

library(ggthemes)

dashboardPage(skin="green",

dashboardHeader(title="Automatic product data display"),

dashboardSidebar(

sidebarMenu(

menuItem("Data",tabName="unload",icon=icon('table'),

menuItem("EAPAlertfile",tabName="Alert",icon=icon('chain')),

menuItem('EAPTrackfile',tabName='Track',icon=icon('chain'))),

menuItem("EAP_Alert",tabName="EAPAlert",icon=icon('plus-circle'),

menuItem("EAPAlert",tabName="EAPAlertChart",icon=icon('bar-chart')),

menuItem("EAPAlert by day",tabName="EAPAlert_Per",icon=icon('bar-chart')),

menuItem("EAPAlert of 24h",tabName="EAPAlert_24",icon=icon('bar-chart'))),

#selectInput("EAPAlert_24","選擇報警",c(unique(Alertfile$process))),

menuItem("EAPtrackout",tabName="EAPTrackChart",icon=icon('train'),

menuItem("EAPTrackin",tabName="EAPTrackinChart",icon=icon('line-chart')),

menuItem("EAPTrackout",tabName="EAPTrackoutChart",icon=icon('line-chart'))),

menuItem("Handle data",tabName="Merge_Analysis",icon=icon('cog'),

menuItem("Merge",tabName="merge_data",icon=icon('th')),

menuItem("Chart anlisis",tabName="TrackAlert_chart",icon=icon('picture-o'))),

selectInput("process","Process seletion",c("Sputter","Coating","Exposing","Developing","Plating","Wet","AOI","Descume","Curing","SAW","LaserMark")),

selectInput("currentstate","EAPAlert station selection",c("S_QueryCarrierInfo","S_CheckRecipeBody","S_QueryLotInfo","S_CheckEquipmentOnOperation")))),

dashboardBody(

tabItems(

tabItem(tabName="Alert",fileInput("EAPAlert_file","Select EAP_Alert.csv file to upload",accept=c('text/csv','text/comma-separated-values,text/plain',".csv")),

DT::dataTableOutput("EAPAlert")),

tabItem(tabName="Track",fileInput("EAPtrack_file","Select EAP track file to upload",accept = c('text/csv','text/comma-separated-values,text/plain',".csv")),

DT::dataTableOutput("EAPtrack")),

tabItem(tabName="EAPAlertChart",

box(title="EAP Alert Chart",width=12,solidHeader = TRUE,status="success",plotOutput("AlertChart"))),

tabItem(tabName="EAPAlert_Per",

box(title="EAP Alert by day",width=12,solidHeader = TRUE,status="success",plotOutput("Alertbyday"))),

tabItem(tabName="EAPAlert_24",

box(title="EAPAlert in 24h",width=12,solidHeader = TRUE,status="success",plotOutput("AlertChart_24"))),

tabItem(tabName="EAPTrackinChart",

box(title="Operation Menthod",width=12,solidHeader=TRUE,status="success",plotOutput("TrackChart"))),

tabItem(tabName="EAPTrackoutChart",

box(title="Lot trackout statistics",width=12,solidHeader=TRUE,status="success",plotOutput("TrackoutChart"))),

tabItem(tabName="merge_data",

fluidRow(

box(title="Data display",width=12,solidHeader=TRUE,status="success",DT::dataTableOutput("TrackAlertfile")),

box(width=2,actionButton("data_merge","Action",icon=icon("car"))))),

tabItem(tabName="TrackAlert_chart",

fluidRow(

box(title="EAP Alert & trackout",width=12,solidHeader=TRUE,status="success",plotOutput("TrackAlertChart"))))

)

)

)

server.R

options(shiny.maxRequestSize=30*1024^2)

function(input,output){

Alertfile

if(is.null(input$EAPAlert_file))

return(NULL)

F

F$gongxu

F$Alarm

attach(F)

F$gongxu[str_detect(sEquipmentId,"AOI")==TRUE]

F$gongxu[str_detect(sEquipmentId,"PLA")==TRUE]

F$gongxu[str_detect(sEquipmentId,"REF")==TRUE]

F$gongxu[str_detect(sEquipmentId,"ETC")==TRUE]

F$gongxu[str_detect(sEquipmentId,"OSB")==TRUE]

F$gongxu[str_detect(sEquipmentId,"STP")==TRUE]

F$gongxu[str_detect(sEquipmentId,"WEE")==TRUE]

F$gongxu[str_detect(sEquipmentId,"SDV")==TRUE]

F$gongxu[str_detect(sEquipmentId,"WYO")==TRUE]

F$gongxu[str_detect(sEquipmentId,"DES")==TRUE]

F$gongxu[str_detect(sEquipmentId,"GPD")==TRUE]

F$gongxu[str_detect(sEquipmentId,"KSM")==TRUE]

F$gongxu[str_detect(sEquipmentId,"NIM")==TRUE]

F$gongxu[str_detect(sEquipmentId,"PVD")==TRUE]

F$gongxu[str_detect(sEquipmentId,"SCB")==TRUE]

F$gongxu[str_detect(sEquipmentId,"MEA")==TRUE]

F$gongxu[str_detect(sEquipmentId,"SAW")==TRUE]

F$gongxu[str_detect(sEquipmentId,"LMK")==TRUE]

F$Alarm[grepl("MES機臺狀態",sErrorContent)==TRUE]

F$Alarm[grepl("MES檢查機臺狀態",sErrorContent)==TRUE]

F$Alarm[grepl("MES檢查機臺工步",sErrorContent)==TRUE]

F$Alarm[grepl("MES檢查PDE設定",sErrorContent)==TRUE]

F$Alarm[grepl("無法與MES",sErrorContent)==TRUE]

F$Alarm[grepl("MES中該Lot",sErrorContent)==TRUE]

F$Alarm[grepl("MES進站失敗",sErrorContent)==TRUE]

F$Alarm[grepl("MES出站失敗",sErrorContent)==TRUE]

F$Alarm[grepl("服務器中不存在當前",sErrorContent)==TRUE]

F$Alarm[grepl("RMS檢查未過關",sErrorContent)==TRUE]

F$Alarm[grepl("超過30天未驗證RMS",sErrorContent)==TRUE]

F$Alarm[grepl("機臺內未找到Lot要用的程序",sErrorContent)==TRUE]

F$Alarm[grepl("機臺未完全IDLE",sErrorContent)==TRUE]

F$Alarm[grepl("機臺拒絕",sErrorContent)==TRUE]

F$Alarm[grepl("機臺設備軟件界面上必須顯示Ready狀態",sErrorContent)==TRUE]

F$Alarm[grepl("機臺前一狀態為ProcessingAbort",sErrorContent)==TRUE]

F$Alarm[grepl("發送PP_Select命令失敗",sErrorContent)==TRUE]

F$Alarm[grepl("類似Lot的程序",sErrorContent)==TRUE]

F$Alarm[grepl("程序不同",sErrorContent)==TRUE]

F$Alarm[grepl("IDLE超過2小時",sErrorContent)==TRUE]

F$Alarm[grepl("光罩",sErrorContent)==TRUE]

F$Alarm[grepl("通過productrrn值找不到相應的數據",sErrorContent)==TRUE]

F$Alarm[grepl("Dummy批次",sErrorContent)==TRUE]

F$Alarm[grepl("無法發送詢問Load命令給機臺",sErrorContent)==TRUE]

F$Alarm[grepl("EAP出站失敗",sErrorContent)==TRUE]

F$Alarm[grepl("掃",sErrorContent)==TRUE]

F$Alarm[grepl("中不存在",sErrorContent)==TRUE]

F$Alarm[grepl("mismatch",sErrorContent)==TRUE]

F$Alarm[grepl("超過2小時",sErrorContent)==TRUE]

F$Alarm[grepl("不在OnlineRemote",sErrorContent)==TRUE]

F$Alarm[grepl("請通知CIM值班人員",sErrorContent)==TRUE]

F$Alarm[grepl("首檢",sErrorContent)==TRUE]

F$Alarm[grepl("已劃過",sErrorContent)==TRUE]

F$Alarm[grepl("腔體實際",sErrorContent)==TRUE]

detach(F)

print(F)

})

Trackfile

if(is.null(input$EAPtrack_file))

return(NULL)

T

attach(T)

T$trackInEmp[str_detect(trackInEmp,'^[0-9]')==TRUE]

# T$trackOutEmp[str_detect(trackOutEmp,'[0-9]')==TRUE]

T$trackOutEmp[str_detect(trackOutEmp,"[a-zA-Z0-9]")==FALSE]

# 工序劃分

T$gongxu[str_detect(machineId,"AOI")==TRUE]

T$gongxu[str_detect(machineId,"PLA")==TRUE]

T$gongxu[str_detect(machineId,"REF")==TRUE]

T$gongxu[str_detect(machineId,"ETC")==TRUE]

T$gongxu[str_detect(machineId,"OSB")==TRUE]

T$gongxu[str_detect(machineId,"STP")==TRUE]

T$gongxu[str_detect(machineId,"WEE")==TRUE]

T$gongxu[str_detect(machineId,"SDV")==TRUE]

T$gongxu[str_detect(machineId,"MEA")==TRUE]

T$gongxu[str_detect(machineId,"WYO")==TRUE]

T$gongxu[str_detect(machineId,"DES")==TRUE]

T$gongxu[str_detect(machineId,"GPD")==TRUE]

T$gongxu[str_detect(machineId,"KSM")==TRUE]

T$gongxu[str_detect(machineId,"NIM")==TRUE]

T$gongxu[str_detect(machineId,"PVD")==TRUE]

T$gongxu[str_detect(machineId,"SCB")==TRUE]

T$gongxu[str_detect(machineId,"SAW")==TRUE]

T$gongxu[str_detect(machineId,"LMK")==TRUE]

detach(T)

print(T)

})

output$EAPAlert

DT::datatable(Alertfile(),rownames = F)

})

output$EAPtrack

DT::datatable(Trackfile(),rownames= F)

})

output$AlertChart

if(is.null(input$EAPAlert_file))

return(NULL)

A

A%>%filter(gongxu==input$process)%>%

ggplot(aes(x=sEquipmentId,fill=Alarm))+

geom_bar(stat="count",position="stack")+theme_economist()+

theme(axis.title.y=element_blank(),axis.title.x=element_blank(),legend.position = "bottom",legend.text=element_text(size=10))+

geom_text(aes(label=..count..),stat="count")+

coord_flip()

})

output$Alertbyday

if(is.null(input$EAPAlert_file))

return(NULL)

A

A%>%filter(gongxu==input$process)%>%

filter(sCurrentState==input$currentstate)%>%

separate(tCreationDate,c("Date","Time"),sep=' ')%>%

group_by(Date,sCurrentState)%>%

summarise(number=n())%>%

ggplot(aes(x=Date,y=number))+geom_bar(stat="identity",fill="red")+theme_economist()+

geom_text(aes(label=number))+

theme(axis.title=element_blank())

})

# 查看24小時報警圖,確認是否網絡問題導致

output$AlertChart_24

if(is.null(input$EAPAlert_file))

return(NULL)

A

A%>%filter(sCurrentState==input$currentstate)%>%

filter(gongxu==input$process)%>%

separate(tCreationDate,c("Date","Time"),sep=' ')%>%

separate(Time,c("Hour","Min"),sep=":")%>%unite(Minute,Hour,Min,sep=":")%>%

group_by(sCurrentState,Minute)%>%

summarise(number=n())%>%

ggplot(aes(x=as.factor(Minute),y=number))+geom_bar(stat="identity",fill="red")+theme_economist()+

theme(axis.text.x=element_text(angle=90),axis.title.x=element_blank())

})

#進站review

output$TrackChart

if(is.null(input$EAPtrack_file))

return(NULL)

T

T%>%filter(gongxu==input$process)%>%

ggplot(aes(machineId,fill=trackInEmp))+

geom_bar(stat="count",position="stack")+theme_economist()+

theme(axis.title.y=element_blank(),legend.position = "top",axis.title.x=element_blank())+

geom_text(aes(label=..count..),stat="count")+coord_flip()

})

#出站異常問題查看

output$TrackoutChart

if(is.null(input$EAPtrack_file))

return(NULL)

T

T%>%filter(gongxu==input$process)%>%

ggplot(aes(machineId,fill=trackOutEmp))+

geom_bar(stat="count",position="stack")+theme_economist()+

theme(axis.title.y = element_blank(),legend.position = "top",axis.title.x=element_blank())+

geom_text(aes(label=..count..),stat="count")+coord_flip()

})

Merge_file

if(is.null(input$EAPtrack_file)|is.null(input$EAPAlert_file))

return(NULL)

Af

Tf

F

print(F)

})

output$TrackAlertfile

DT::datatable(Merge_file(),rownames = F)

})

output$TrackAlertChart

M

M%>%filter(gongxu.x==input$process)%>%filter(trackInEmp!='NA')%>%

ggplot(aes(as.factor(Alarm),sLotId,color=trackInEmp))+geom_point()+theme_economist()+

theme(axis.text.x=element_text(angle=90 ,color='red',vjust=0),axis.title.x=element_blank(),legend.position="top")

#nPlot(sEquipmentId~lotId,group='trackOutEmp',data=M,type="scatterChart")

})

}

運行代碼後:

工廠自動化數據Shiny App展示

工廠自動化數據Shiny App展示

因部分原因無法連接數據庫,使用本地上傳文件的方式

工廠自動化數據Shiny App展示

工廠自動化數據Shiny App展示

工廠自動化數據Shiny App展示

工廠自動化數據Shiny App展示

24H分析報警,有時需要確認在同1分鐘內某個報警是否增多,來判斷網絡異常

工廠自動化數據Shiny App展示

過站信息統計,非EAP和EAP

工廠自動化數據Shiny App展示

出站信息統計

工廠自動化數據Shiny App展示

報警和進站的關係圖


分享到:


相關文章: