Source Code

原始碼如下,使用介面 請按此

library(shiny)
library(dplyr)
library(shinyTime)

# for time zone
cuts <- c(-Inf, -172.5, -157.5, -142.5, -127.5, -112.5, -97.5, -82.5, -67.5,
          -52.5, -37.5, -22.5, -7.5, 7.5, 22.5, 37.5, 52.5, 
          67.5, 82.5, 97.5, 112.5, 127.5, 142.5, 157.5, 172.5, Inf)

labs <- c("-180", "-165", "-150", "-135", "-120", "-105", "-90", "-75", 
          "-60", "-45", "-30", "-15", "0", "15", "30", "45", "60", 
          "75", "90", "105", "120", "135", "150", "165", "180")


# Define UI for application that draws a histogram
ui <- fluidPage(
  
   # Application title
   titlePanel("Solar Calculator"),
   
   p("created by I-Ting Lai"),

   # Sidebar with a slider input for number of bins 
   sidebarLayout(
      sidebarPanel(

        # date 
        dateInput(inputId = "date", label = "Date input", value = "2017-01-01"),
        # time
        timeInput(inputId = "time", label = "Time [Hour/Minute/Second]"),
        
        hr(),
        
        # Latitude, Longitude
        numericInput(inputId = "long", label = "Longitude [Degree East]", value = 120,
                     min = -180, max = 180),
        numericInput(inputId = "lat", label = "Latitude [Degree North]", value = 23.5,
                     min = -90, max = 90),
        hr(),
        
        # Surface Tilt Angle (β)
        numericInput(inputId = "surtl_angle", label = "Surface Tilt Angle [Degree]", value = 0,
                     min = 0, max = 180),
        helpText("* Flat: 0, vertical: 90"),
        # Surface Azimuth Angle
        numericInput(inputId = "suraz_angle", label = "Surface Azimuth Angle [Degree]", value = 0),
        helpText("* Facing south: 0, facing east: -90"),
        
        hr(),
        
        # Beam Normal Solar Radiation
        numericInput(inputId = "bn_solradiation", label = "Beam Normal Solar Radiation [W/m2]", 
                     value = 0, min = 0, max = 1367),
        
        submitButton("Update View")
      ),
      
      
      # Show a plot of the generated distribution
      mainPanel(
        
         h4("Result"),
         tableOutput("table")
         
      )
   )
)


# sin cos is radian, degree * (pi/180) = radian

# Define server logic required to draw a histogram
server <- function(input, output) {
  
   # 表格-------------------------
  
   dataInput <- reactive({
     
     # n --------------------------------
     n <- format(input$date, "%j") %>% as.integer()
     # ----------------------------------
     
     # Equation of time (min) -----------
     eqt <- ( 9.87*sin( 4*pi*(n-81)/364 ) - 7.53*cos( 2*pi*(n-81)/364 ) - 1.5*sin( 2*pi*(n-81)/364 ) )
     # ----------------------------------
     
     # Local time (hour) ----------------
     x.lt <- as.POSIXlt(input$time)
     local_time <- as.numeric(x.lt$hour + x.lt$min/60 + x.lt$sec/3600)
     # ----------------------------------
     
     # Standard longitude (degree) ------
     Ls <- cut(input$long, breaks = cuts, labels = labs, include.lowest = TRUE) %>%
       as.character() %>%
       as.numeric() 
     # ----------------------------------
     
     # Solar time (hour) ----------------
     sol_time <- local_time + eqt/60 + (Ls - input$long)/15
     # ----------------------------------     
     
     # Solar hour angle (degree) --------
     sol_hour <- (sol_time - 12)*15
     # ----------------------------------
     
     # Solar declination (degree) -------
     sol_declin <- 23.45*sin( 360*(284+n)/365 * (pi/180) ) # check
     # ----------------------------------
     
     # solar altitude -------------------
     sol_alti <- asin( cos( input$lat*(pi/180) ) * cos( sol_declin*(pi/180) ) * cos( sol_hour*(pi/180) ) + sin( input$lat*(pi/180) ) * sin( sol_declin*(pi/180) ) )
     sol_alti_degree <- sol_alti*(180/pi) # degree
     # ----------------------------------
    
     # solar zenith (degree) ------------
     sol_zen_degree <- 90 - sol_alti_degree
     # ----------------------------------
     
     # solar azimuth (degree) -----------
     # 分子
     numerator <- sin( sol_alti_degree*(pi/180) ) * sin( input$lat*(pi/180) ) - sin( sol_declin*(pi/180) )
     # 分母
     denominator <- cos( sol_alti_degree*(pi/180) ) * cos( input$lat*(pi/180) )
     
     sol_azim <- acos(numerator/denominator) * (sol_hour*(pi/180)/abs(sol_hour*(pi/180)))     
     sol_azim_degree <- sol_azim*(180/pi) # degree
     # ----------------------------------
     
     # Surface solar azimuth (degree) ----
     sur_sol_azim_degree <- abs(sol_azim_degree - input$suraz_angle)
     # ----------------------------------
     
     # Incident angle (degree) ----------
     incident_angle <- acos( cos( sol_alti_degree*(pi/180) ) * cos( sur_sol_azim_degree*(pi/180) ) * sin( input$surtl_angle*(pi/180) ) + sin( sol_alti_degree*(pi/180) ) * cos( input$surtl_angle*(pi/180) ) )
     incident_angle_degree <- incident_angle*(180/pi) # degree
     # ----------------------------------
     
     # Beam Solar Radiation on any Surface ----
     radiation_on_surface <- input$bn_solradiation * cos( incident_angle_degree*(pi/180) )
     # ----------------------------------
     
     # Compose data frame
     data.frame(
       Item = c("Day of the year", 
                "Equation of time",
                "Solar time",
                "Solar hour angle",
                "Solar declination",
                "Solar altitude",
                "Solar zenith",
                "Solar azimuth",
                "Surface solar azimuth",
                "Incident angle",
                "Beam solar radiation on the surface"),
       Value = as.numeric(c(n,
                            round(eqt, digits = 2),
                            round(sol_time, digits = 2),
                            round(sol_hour, digits = 2),
                            round(sol_declin, digits = 2),
                            round(sol_alti_degree, digits = 2), 
                            round(sol_zen_degree, digits = 2), 
                            round(sol_azim_degree, digits = 2),
                            round(sur_sol_azim_degree, digits = 2),
                            round(incident_angle_degree, digits = 2),
                            round(radiation_on_surface, digits = 2))), 
       Units = c("day",
                 "min",
                 "hour",
                 "degree",
                 "degree",
                 "degree",
                 "degree",
                 "degree", 
                 "degree",
                 "degree",
                 "W/m2"),
       Details = c("",
                   "",
                   "",
                   "",
                   "",
                   "horizon: 0",
                   "",
                   "south: 0, west: 90, east: -90",
                   "",
                   "",
                   ""),
       stringsAsFactors = FALSE)
     
   })
   
   output$table <- renderTable({
     dataInput() # 輸出表格
   })
 
   # -----------------------------

}

# Run the application 
shinyApp(ui = ui, server = server)