diff --git a/rTubeDB/DESCRIPTION b/rTubeDB/DESCRIPTION index 7ea57d66..ab66be00 100644 --- a/rTubeDB/DESCRIPTION +++ b/rTubeDB/DESCRIPTION @@ -1,14 +1,14 @@ -Package: rTubeDB -Type: Package -Title: R connection to TubeDB server -Version: 1.3.3 -Author: woellauer -Maintainer: woellauer -Description: rTubeDB package provides functionality to query and process time series from TubeDB server. -License: GPL 3 -Encoding: UTF-8 -LazyData: true -RoxygenNote: 7.1.1 -Imports: - httr, - ISOweek +Package: rTubeDB +Type: Package +Title: R connection to TubeDB server +Version: 1.4 +Author: woellauer +Maintainer: woellauer +Description: rTubeDB package provides functionality to query and process time series from TubeDB server. +License: GPL 3 +Encoding: UTF-8 +LazyData: true +RoxygenNote: 7.3.2 +Imports: + httr, + ISOweek diff --git a/rTubeDB/R/tubedb.R b/rTubeDB/R/tubedb.R index 6e5e469c..a7236435 100644 --- a/rTubeDB/R/tubedb.R +++ b/rTubeDB/R/tubedb.R @@ -681,6 +681,7 @@ query_region_stations <- function(tubedb, regionID) { #' @param year get data from one full year only (You may use this 'year' parameter OR 'start', 'end' parameters) #' @param month get data of one full month of one year only, parameter year neads to be specified (You may use this 'month' parameter OR 'start'/'end' parameters) #' @param day get data of one full day of one month only, parameter month neads to be specified (You may use this 'day' parameter OR 'start'/'end' parameters) +#' @param quality_counter qualityCounter column to count aggregated measured values and interpolated values #' @param casted all plot-sensor pairs in one row per timestamp, e.g. columns plot1.sensor1, plot2.sensor1, plot1.sensor2 #' @param spatial_aggregated combine all values of one sensor over all plots to one value per timestamp by mean #' @param datetimeFormat character, requested type of timestamps. one of: "character", "POSIXct", "POSIXlt" @@ -718,7 +719,7 @@ query_region_stations <- function(tubedb, regionID) { #' # show time series #' plot(tsDF$datetime, tsDF$Ta_200) #' @export -query_timeseries <- function(tubedb, plot, sensor, aggregation = "hour", quality = "physical", interpolated = FALSE, start = NULL, end = NULL, year = NULL, month = NULL, day = NULL, casted = FALSE, spatial_aggregated = FALSE, datetimeFormat = "character", colYear = FALSE, colPlot = TRUE, colMonth = FALSE, colDay = FALSE, colHour = FALSE, colWeek = FALSE, colDayOfWeek = FALSE, colDayOfYear = FALSE, colMinute = FALSE) { +query_timeseries <- function(tubedb, plot, sensor, aggregation = "hour", quality = "physical", interpolated = FALSE, start = NULL, end = NULL, year = NULL, month = NULL, day = NULL, quality_counter = FALSE, casted = FALSE, spatial_aggregated = FALSE, datetimeFormat = "character", colYear = FALSE, colPlot = TRUE, colMonth = FALSE, colDay = FALSE, colHour = FALSE, colWeek = FALSE, colDayOfWeek = FALSE, colDayOfYear = FALSE, colMinute = FALSE) { stopifnot(isClass(tubedb, TubeDB)) args <- list( aggregation = aggregation, @@ -729,6 +730,7 @@ query_timeseries <- function(tubedb, plot, sensor, aggregation = "hour", quality year = year, month = month, day = day, + quality_counter = quality_counter, casted = casted, spatial_aggregated = spatial_aggregated, col_plot = colPlot diff --git a/rTubeDB/man/query_timeseries.Rd b/rTubeDB/man/query_timeseries.Rd index 00d2d8f0..6cbd2db4 100644 --- a/rTubeDB/man/query_timeseries.Rd +++ b/rTubeDB/man/query_timeseries.Rd @@ -16,6 +16,7 @@ query_timeseries( year = NULL, month = NULL, day = NULL, + quality_counter = FALSE, casted = FALSE, spatial_aggregated = FALSE, datetimeFormat = "character", @@ -23,7 +24,11 @@ query_timeseries( colPlot = TRUE, colMonth = FALSE, colDay = FALSE, - colHour = FALSE + colHour = FALSE, + colWeek = FALSE, + colDayOfWeek = FALSE, + colDayOfYear = FALSE, + colMinute = FALSE ) } \arguments{ @@ -49,6 +54,8 @@ query_timeseries( \item{day}{get data of one full day of one month only, parameter month neads to be specified (You may use this 'day' parameter OR 'start'/'end' parameters)} +\item{quality_counter}{qualityCounter column to count aggregated measured values and interpolated values} + \item{casted}{all plot-sensor pairs in one row per timestamp, e.g. columns plot1.sensor1, plot2.sensor1, plot1.sensor2} \item{spatial_aggregated}{combine all values of one sensor over all plots to one value per timestamp by mean} @@ -64,6 +71,14 @@ query_timeseries( \item{colDay}{add numeric day column in resulting data.frame (1 to 31)} \item{colHour}{add numeric hour column in resulting data.frame (0 to 23)} + +\item{colWeek}{add numeric day of week column in resulting data.frame (1 to 53) (ISO week based)} + +\item{colDayOfWeek}{add numeric day of week column in resulting data.frame (1 to 7) (ISO week based)} + +\item{colDayOfYear}{add numeric day of year column in resulting data.frame (1 to 366)} + +\item{colMinute}{add numeric minute in resulting data.frame (0 to 59)} } \value{ data.frame time series with datetime column + sensor columns diff --git a/rTubeDB/man/read_timeseries.Rd b/rTubeDB/man/read_timeseries.Rd index 8af90eec..c9e8510b 100644 --- a/rTubeDB/man/read_timeseries.Rd +++ b/rTubeDB/man/read_timeseries.Rd @@ -10,7 +10,11 @@ read_timeseries( colYear = FALSE, colMonth = FALSE, colDay = FALSE, - colHour = FALSE + colHour = FALSE, + colWeek = FALSE, + colDayOfWeek = FALSE, + colDayOfYear = FALSE, + colMinute = FALSE ) } \arguments{ @@ -25,6 +29,14 @@ read_timeseries( \item{colDay}{add numeric day column in resulting data.frame (1 to 31)} \item{colHour}{add numeric hour column in resulting data.frame (0 to 23)} + +\item{colWeek}{add numeric day of week column in resulting data.frame (1 to 53) (ISO week based)} + +\item{colDayOfWeek}{add numeric day of week column in resulting data.frame (1 to 7) (ISO week based)} + +\item{colDayOfYear}{add numeric day of year column in resulting data.frame (1 to 366)} + +\item{colMinute}{add numeric minute in resulting data.frame (0 to 59)} } \value{ data.frame time series with datetime column + sensor columns diff --git a/src/tsdb/TsDB.java b/src/tsdb/TsDB.java index 4ee382d3..361b8672 100644 --- a/src/tsdb/TsDB.java +++ b/src/tsdb/TsDB.java @@ -33,7 +33,7 @@ */ public class TsDB implements AutoCloseable { - public static final String tubedb_version = "1.31.2"; + public static final String tubedb_version = "1.32"; /** * map regionName -> Region diff --git a/src/tsdb/web/api/Handler_monitoring.java b/src/tsdb/web/api/Handler_monitoring.java index 5a24d13f..5197e9e0 100644 --- a/src/tsdb/web/api/Handler_monitoring.java +++ b/src/tsdb/web/api/Handler_monitoring.java @@ -14,6 +14,7 @@ import tsdb.util.DataEntry; import tsdb.util.Measurement; import tsdb.util.TimeUtil; +import tsdb.web.util.Web; public class Handler_monitoring extends MethodHandler { @@ -26,8 +27,8 @@ public void handle(String target, Request baseRequest, HttpServletRequest reques baseRequest.setHandled(true); response.setContentType("application/json;charset=utf-8"); - String[] plotIDs = request.getParameterValues("plot"); - String[] sensorNames = request.getParameterValues("sensor"); + String[] plotIDs = Web.getStrings(baseRequest, "plot"); + String[] sensorNames = Web.getStrings(baseRequest, "sensor"); ArrayList result = tsdb.getMonitoring(plotIDs, sensorNames); diff --git a/src/tsdb/web/api/Handler_query_csv.java b/src/tsdb/web/api/Handler_query_csv.java index 22485593..eba58fe6 100644 --- a/src/tsdb/web/api/Handler_query_csv.java +++ b/src/tsdb/web/api/Handler_query_csv.java @@ -27,6 +27,7 @@ import tsdb.util.iterator.CSVTimeType; import tsdb.util.iterator.TimestampSeries; import tsdb.util.iterator.TsIterator; +import tsdb.web.util.Web; /** * Get timeseries data as CSV-file. @@ -90,7 +91,7 @@ public void handle(String target, Request baseRequest, HttpServletRequest reques response.setStatus(HttpServletResponse.SC_BAD_REQUEST); return; } - String[] plots = request.getParameterValues("plot"); + String[] plots = Web.getStrings(baseRequest, "plot"); String col_plot_text = request.getParameter("col_plot"); boolean col_plot = false; @@ -108,8 +109,7 @@ public void handle(String target, Request baseRequest, HttpServletRequest reques } } - //String sensorName = request.getParameter("sensor"); - String[] sensorNames = request.getParameterValues("sensor"); + String[] sensorNames = Web.getStrings(baseRequest, "sensor"); if(sensorNames==null) { Logger.warn("wrong call no sensor"); @@ -146,6 +146,22 @@ public void handle(String target, Request baseRequest, HttpServletRequest reques casted = false; } } + + String quality_counter_text = request.getParameter("quality_counter"); + boolean quality_counter = false; + if(quality_counter_text != null) { + switch(quality_counter_text) { + case "true": + quality_counter = true; + break; + case "false": + quality_counter = false; + break; + default: + Logger.warn("unknown input"); + quality_counter = false; + } + } String spatial_aggregated_text = request.getParameter("spatial_aggregated"); boolean spatial_aggregated = false; @@ -331,14 +347,14 @@ public void handle(String target, Request baseRequest, HttpServletRequest reques TimestampSeries ts = tsdb.plots_aggregate(plots, processingSensorNames, agg, dataQuality, isInterpolated, startTime, endTime); if(ts != null) { TsIterator it = ts.tsIterator(); - CSV.write(it, true, bufferedWriter, ',', nanText, csvTimeType, false, false, agg, null); + CSV.write(it, true, bufferedWriter, ',', nanText, csvTimeType, false, quality_counter, agg, null); } } else { if(casted) { TimestampSeries ts = tsdb.plots_casted(plots, processingSensorNames, agg, dataQuality, isInterpolated, startTime, endTime); if(ts != null) { TsIterator it = ts.tsIterator(); - CSV.write(it, true, bufferedWriter, ',', nanText, csvTimeType, false, false, agg, null); + CSV.write(it, true, bufferedWriter, ',', nanText, csvTimeType, false, quality_counter, agg, null); } } else { boolean firstPlot = true; @@ -351,7 +367,7 @@ public void handle(String target, Request baseRequest, HttpServletRequest reques if(ts != null) { ProjectionFillIterator it = new ProjectionFillIterator(ts.tsIterator(), processingSensorNames); String plot_text = col_plot ? plot : null; - CSV.write(it, firstPlot, bufferedWriter, ',', nanText, csvTimeType, false, false, agg, plot_text); + CSV.write(it, firstPlot, bufferedWriter, ',', nanText, csvTimeType, false, quality_counter, agg, plot_text); firstPlot = false; } } catch (Exception e) { diff --git a/src/tsdb/web/util/Web.java b/src/tsdb/web/util/Web.java index 69c047ff..3a9aff0b 100644 --- a/src/tsdb/web/util/Web.java +++ b/src/tsdb/web/util/Web.java @@ -181,5 +181,19 @@ public static byte[] readAllBytes(InputStream in, int startBufferSize) throws IO } return (capacity == nread) ? buf : Arrays.copyOf(buf, nread); } - + + /** + * Array of all parameters of same name and each parameter split by semicolon ','. + * @param request + * @param name + * @return + */ + public static String[] getStrings(Request request, String name) { + String[] texts = request.getParameterValues(name); + if(texts == null) { + throw new RuntimeException("parameter not found: "+name); + } + String[] splitTexts = Arrays.stream(texts).flatMap(text -> Arrays.stream(text.split(","))).toArray(String[]::new); + return splitTexts; + } }