R version 4.5.2 (2025-10-31) -- "[Not] Part in a Rumble" Copyright (C) 2025 The R Foundation for Statistical Computing Platform: x86_64-pc-linux-gnu R is free software and comes with ABSOLUTELY NO WARRANTY. You are welcome to redistribute it under certain conditions. Type 'license()' or 'licence()' for distribution details. Natural language support but running in an English locale R is a collaborative project with many contributors. Type 'contributors()' for more information and 'citation()' on how to cite R or R packages in publications. Type 'demo()' for some demos, 'help()' for on-line help, or 'help.start()' for an HTML browser interface to help. Type 'q()' to quit R. > library(lubridate) Attaching package: ‘lubridate’ The following objects are masked from ‘package:base’: date, intersect, setdiff, union > library(plotly) Loading required package: ggplot2 Attaching package: ‘plotly’ The following object is masked from ‘package:ggplot2’: last_plot The following object is masked from ‘package:stats’: filter The following object is masked from ‘package:graphics’: layout > library(htmlwidgets) > library(weathermetrics) # install.packages("weathermetrics") > library(heatindex) # install.packages("heatindex") > > # Set Time-Period > actTime = Sys.time() > timePer = 7 * 24 * 3600 > startTime = actTime - timePer > actYear = year(actTime) > actMonth = month(actTime) > lstYear = year(actTime - timePer) > lstMonth = month(actTime - timePer) > # Construct paths and filenames > # Senesecaps Description > # 1 "2CF7F1C0532000D2" # Außenbereich Kita (zwischen Schaukel und Gerüst, hinter einer Sitzbank) > # 2 "2CF7F1C053200114" # Baum zwischen Außenbereich Kita und Außenbereich Hort neben dem Sandkasten Kita > # 3 "2CF7F1C0532000BD" # Außenbereich Krippe, Baum am Sandkasten Krippe > # Sensecap Names > s_names = c("2CF7F1C0532000D2", "2CF7F1C053200114","2CF7F1C0532000BD") > s_labels = c("Schoenbach 1", "Schoenbach 2", "Schoenbach 3") > path_1 = "https://saqn.geo.uni-augsburg.de" > path_2 = "lorawan" > path_3_y = c(lstYear, actYear) > path_3_m = c(lstMonth, actMonth) > > for(mCt in 1:length(path_3_m)) + { + path_3_ym = paste(path_3_y[mCt], formatC(path_3_m[mCt], width = 2, format = "d", flag = "0"), sep ="-") + print(path_3_ym) + for(s_name in s_names) + { + # Sensecap Data + URL = paste(path_1, "/",path_2, "/",path_3_ym, "/",s_name, "_",path_3_ym, ".csv", sep = "") + try(download.file(URL, destfile = "download_scap.dat", method = "wget", extra = "--no-check-certificate"), silent = TRUE) + hdr1 = read.table("download_scap.dat", sep = ",", nrows = 1) + header = c(hdr1, "sc_id") + dF = read.table("download_scap.dat", header = FALSE, sep = ",", na.strings = c(-9999) , skip = 1) + dF$sc_id = s_name + names(dF) = header; names(dF) = trimws(names(dF), which = "left") + if(mCt == 1 & s_name == s_names[1]) + {pscData = dF}else{pscData = rbind(pscData, dF)} + } + } [1] "2026-08" --2026-08-20 19:26:56-- https://saqn.geo.uni-augsburg.de/lorawan/2026-08/2CF7F1C0532000D2_2026-08.csv Resolving saqn.geo.uni-augsburg.de (saqn.geo.uni-augsburg.de)... 137.250.104.17 Connecting to saqn.geo.uni-augsburg.de (saqn.geo.uni-augsburg.de)|137.250.104.17|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 409590 (400K) [text/csv] Saving to: ‘download_scap.dat’ 0K .......... .......... .......... .......... .......... 12% 119M 0s 50K .......... .......... .......... .......... .......... 25% 208M 0s 100K .......... .......... .......... .......... .......... 37% 276M 0s 150K .......... .......... .......... .......... .......... 50% 327M 0s 200K .......... .......... .......... .......... .......... 62% 303M 0s 250K .......... .......... .......... .......... .......... 75% 311M 0s 300K .......... .......... .......... .......... .......... 87% 320M 0s 350K .......... .......... .......... .......... ......... 100% 327M=0.002s 2026-08-20 19:26:56 (245 MB/s) - ‘download_scap.dat’ saved [409590/409590] --2026-08-20 19:26:56-- https://saqn.geo.uni-augsburg.de/lorawan/2026-08/2CF7F1C053200114_2026-08.csv Resolving saqn.geo.uni-augsburg.de (saqn.geo.uni-augsburg.de)... 137.250.104.17 Connecting to saqn.geo.uni-augsburg.de (saqn.geo.uni-augsburg.de)|137.250.104.17|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 127648 (125K) [text/csv] Saving to: ‘download_scap.dat’ 0K .......... .......... .......... .......... .......... 40% 126M 0s 50K .......... .......... .......... .......... .......... 80% 161M 0s 100K .......... .......... .... 100% 388M=0.001s 2026-08-20 19:26:56 (161 MB/s) - ‘download_scap.dat’ saved [127648/127648] --2026-08-20 19:26:56-- https://saqn.geo.uni-augsburg.de/lorawan/2026-08/2CF7F1C0532000BD_2026-08.csv Resolving saqn.geo.uni-augsburg.de (saqn.geo.uni-augsburg.de)... 137.250.104.17 Connecting to saqn.geo.uni-augsburg.de (saqn.geo.uni-augsburg.de)|137.250.104.17|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 329616 (322K) [text/csv] Saving to: ‘download_scap.dat’ 0K .......... .......... .......... .......... .......... 15% 137M 0s 50K .......... .......... .......... .......... .......... 31% 169M 0s 100K .......... .......... .......... .......... .......... 46% 246M 0s 150K .......... .......... .......... .......... .......... 62% 269M 0s 200K .......... .......... .......... .......... .......... 77% 243M 0s 250K .......... .......... .......... .......... .......... 93% 265M 0s 300K .......... .......... . 100% 222M=0.002s 2026-08-20 19:26:56 (209 MB/s) - ‘download_scap.dat’ saved [329616/329616] [1] "2026-08" --2026-08-20 19:26:56-- https://saqn.geo.uni-augsburg.de/lorawan/2026-08/2CF7F1C0532000D2_2026-08.csv Resolving saqn.geo.uni-augsburg.de (saqn.geo.uni-augsburg.de)... 137.250.104.17 Connecting to saqn.geo.uni-augsburg.de (saqn.geo.uni-augsburg.de)|137.250.104.17|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 409590 (400K) [text/csv] Saving to: ‘download_scap.dat’ 0K .......... .......... .......... .......... .......... 12% 211M 0s 50K .......... .......... .......... .......... .......... 25% 225M 0s 100K .......... .......... .......... .......... .......... 37% 310M 0s 150K .......... .......... .......... .......... .......... 50% 314M 0s 200K .......... .......... .......... .......... .......... 62% 289M 0s 250K .......... .......... .......... .......... .......... 75% 314M 0s 300K .......... .......... .......... .......... .......... 87% 317M 0s 350K .......... .......... .......... .......... ......... 100% 292M=0.001s 2026-08-20 19:26:56 (278 MB/s) - ‘download_scap.dat’ saved [409590/409590] --2026-08-20 19:26:56-- https://saqn.geo.uni-augsburg.de/lorawan/2026-08/2CF7F1C053200114_2026-08.csv Resolving saqn.geo.uni-augsburg.de (saqn.geo.uni-augsburg.de)... 137.250.104.17 Connecting to saqn.geo.uni-augsburg.de (saqn.geo.uni-augsburg.de)|137.250.104.17|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 127648 (125K) [text/csv] Saving to: ‘download_scap.dat’ 0K .......... .......... .......... .......... .......... 40% 230M 0s 50K .......... .......... .......... .......... .......... 80% 278M 0s 100K .......... .......... .... 100% 304M=0s 2026-08-20 19:26:56 (261 MB/s) - ‘download_scap.dat’ saved [127648/127648] --2026-08-20 19:26:56-- https://saqn.geo.uni-augsburg.de/lorawan/2026-08/2CF7F1C0532000BD_2026-08.csv Resolving saqn.geo.uni-augsburg.de (saqn.geo.uni-augsburg.de)... 137.250.104.17 Connecting to saqn.geo.uni-augsburg.de (saqn.geo.uni-augsburg.de)|137.250.104.17|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 329616 (322K) [text/csv] Saving to: ‘download_scap.dat’ 0K .......... .......... .......... .......... .......... 15% 188M 0s 50K .......... .......... .......... .......... .......... 31% 199M 0s 100K .......... .......... .......... .......... .......... 46% 294M 0s 150K .......... .......... .......... .......... .......... 62% 310M 0s 200K .......... .......... .......... .......... .......... 77% 277M 0s 250K .......... .......... .......... .......... .......... 93% 311M 0s 300K .......... .......... . 100% 256M=0.001s 2026-08-20 19:26:56 (252 MB/s) - ‘download_scap.dat’ saved [329616/329616] > # Format Date and Time > pscData$time = as.POSIXct(pscData$time, format = "%Y-%m-%dT%H:%M:%OSZ", tz = "UTC") > pscData$time = round_date(pscData$time, "10 minutes") > > # Remove duplicated DateTime entries > if(length(which(duplicated(paste(pscData$time, pscData$sc_id))) > 0)) pscData = pscData[-which(duplicated(paste(pscData$time, pscData$sc_id))),] > > # Calculate HI > # heat.index from weathermetrics (National Weather Service Hydrometeorological Prediction Center Web Team. Heat Index Calculator. 30 Jan 2015. http://www.wpc.ncep.noaa.gov/html/heatindex.shtml. Accessed 18 Dec 2015) > pscData$heatIndex_01 = heat.index(t = pscData$airTemperature, rh = pscData$relativeHumidity, temperature.metric = "celsius", output.metric = NULL, round = 2) > # heatindex from heatindex (Steadman, R. G. (1979). The assessment of sultriness. Part I: A temperature-humidity index based on human physiology and clothing science. Journal of Applied Meteorology, 18, 861-873. doi:10.1175/1520-0450(1979)018<0861:TAOSPI>2.0.CO;2) > pscData$heatIndex_02 = heatindex(T = (pscData$airTemperature + 273.16), rh = (pscData$relativeHumidity * 0.01)) - 273.16 > # HI-Risk-Levels > HI_Levs = c(27, 32, 39, 52) > HI_cats = c("Caution", "Extreme Caution", "Danger", "Extreme Danger") > HI_shapes <- lapply(HI_Levs, function(y) { + list( + type = "line", + x0 = 0, x1 = 1, + xref = "paper", + y0 = y, y1 = y, + yref = "y", + line = list(color = "grey60", width = 1, dash = "dot") + ) + }) > HI_annotations <- lapply(seq_along(HI_Levs), function(i) { + list( + x = 1, + xref = "paper", + y = HI_Levs[i], + yref = "y", + text = paste("HI > ",HI_Levs[i],"°C : ", HI_cats[i]), + showarrow = FALSE, + xanchor = "left", + xshift = 8, + font = list( + size = 18, + color = "grey30" + ) + ) + }) > > > # Cut data to time period > pscdata = subset(pscData, time > startTime) # Sensecap Data > #pscdata = pscdata[order(pscdata$time),] > > cl = c("#FF4500", "#CD3700", "#8B2500") > > # Subplots > # Sensecap plots > fig_sc_temp = plot_ly(data = pscdata[pscdata$sc_id == s_names[1],], x = ~time, y = ~airTemperature, name = paste(s_labels[1], " (Ta)"), type = 'scatter', mode = 'lines', line = list(width = 3, color = cl[1])) %>% + add_lines(data = pscdata[pscdata$sc_id == s_names[2],], x = ~time, y = ~airTemperature, name = paste(s_labels[2], " (Ta)"), type = 'scatter', mode = 'lines', line = list(color = cl[2])) %>% + add_lines(data = pscdata[pscdata$sc_id == s_names[3],], x = ~time, y = ~airTemperature, name = paste(s_labels[3], " (Ta)"), type = 'scatter', mode = 'lines', line = list(color = cl[3])) > > fig_sc_rhum = plot_ly(data = pscdata[pscdata$sc_id == s_names[1],], x = ~time, y = ~relativeHumidity, name = paste(s_labels[1], " (RH)"), type = 'scatter', mode = 'lines', line = list(width = 3, color = cl[1], dash = "dash")) %>% + add_lines(data = pscdata[pscdata$sc_id == s_names[2],], x = ~time, y = ~relativeHumidity, name = paste(s_labels[2], " (RH)"), type = 'scatter', mode = 'lines', line = list(color = cl[2])) %>% + add_lines(data = pscdata[pscdata$sc_id == s_names[3],], x = ~time, y = ~relativeHumidity, name = paste(s_labels[3], " (RH)"), type = 'scatter', mode = 'lines', line = list(color = cl[3])) > > fig_sc_hi_01 = plot_ly(data = pscdata[pscdata$sc_id == s_names[1],], x = ~time, y = ~heatIndex_01, name = paste(s_labels[1], " (HI)"), type = 'scatter', mode = 'lines', line = list(width = 3, color = cl[1], dash = "dot")) %>% + add_lines(data = pscdata[pscdata$sc_id == s_names[2],], x = ~time, y = ~heatIndex_01, name = paste(s_labels[2], " (HI)"), type = 'scatter', mode = 'lines', line = list(color = cl[2])) %>% + add_lines(data = pscdata[pscdata$sc_id == s_names[3],], x = ~time, y = ~heatIndex_01, name = paste(s_labels[3], " (HI)"), type = 'scatter', mode = 'lines', line = list(color = cl[3])) %>% + layout( + shapes = HI_shapes, + annotations = HI_annotations) > > fig_sc_hi_02 = plot_ly(data = pscdata[pscdata$sc_id == s_names[1],], x = ~time, y = ~heatIndex_02, name = "IGUA - Bodenstation - HI", type = 'scatter', mode = 'lines', line = list(width = 3, color = cl[1], dash = "dot")) %>% + add_lines(data = pscdata[pscdata$sc_id == s_names[2],], x = ~time, y = ~heatIndex_02, name = "Logger - Friesenstrasse - HI", type = 'scatter', mode = 'lines', line = list(color = cl[2])) %>% + add_lines(data = pscdata[pscdata$sc_id == s_names[3],], x = ~time, y = ~heatIndex_02, name = "Logger - Gärtnerstrasse - HI", type = 'scatter', mode = 'lines', line = list(color = cl[3])) > > > # Stacked Subplots > fig = subplot(fig_sc_temp, fig_sc_rhum, fig_sc_hi_01, nrows = 3, shareX = TRUE, margin = 0.01) %>% + layout( + title = list( + text = "IGUA - Physical Geography and Climate Science - Augsburg Urban Climate Network", + font = list(size = 24, color = "") + ), + margin = list( + l = 80, # left + r = 40, # right + t = 100, # top + b = 80 # bottom + ) + , + plot_bgcolor='#e5ecf6', + xaxis = list( + zerolinecolor = '#ffff', + zerolinewidth = 2, + gridcolor = 'ffff', + title = "Time"), + xaxis2 = list( + zerolinecolor = '#ffff', + zerolinewidth = 2, + gridcolor = 'ffff', + title = "Time"), + yaxis = list(title = list(text = "Air Temperature (°C)", font = list(size = 24, color = ""))), + yaxis2 = list(title = list(text = "Relative Humidity (%)", font = list(size = 24, color = ""))), + yaxis3 = list(title = list(text = "Heat Index (°C)", font = list(size = 24, color = ""))), + legend = list(font = list(size = 20)) + ) > fig > > # Export HTML > saveWidget(fig,"Schoenbach_Sensecap_recent.html", selfcontained = F) > # > > proc.time() user system elapsed 3.153 2.707 3.580