#' Time Series data object
#' @description Object for storing single time series value
#' @details Has standard methods for managing data and meta data
#' @importFrom R6 R6Class
#' @param datasource optional RomDataSource for remote and local storage
#' @param config list of attributes to set
#' @return reference class of type openmi.om.base.
#' @seealso NA
#' @examples NA
#' @export RomTS
RomTS <- R6Class(
"RomTS",
inherit = RomEntity,
public = list(
#' @field base_entity_type kind of entity
base_entity_type = 'dh_timeseries',
#' @field pk_name the name of this entity's pk column
pk_name = 'tid',
#' @field has_vardef is pluggable?
has_vardef = TRUE,
#' @field tid unique ID in this RomDataSource
tid = NA,
#' @field featureid id of entity this is attached to
featureid = NA,
#' @field entity_type type of entity this is attached to
entity_type = NA,
#' @field tstime begin timestamp
tstime = NA,
#' @field tsendtime end time stamp
tsendtime = NA,
#' @field tsvalue numerical value
tsvalue = NA,
#' @field tscode alphanumeric value
tscode = NA,
#' @field tlid timeline ID (for future use)
tlid = NA,
#' @field varid variable ID from RomDataSource
varid = NA,
#' @field bundle (for future use)
bundle = NA,
#' @field uid user id of creator
uid = NA,
#' @field modified timestamp
modified = NA,
#' @field datasource RomDataSource
datasource = NA,
#' @field sql_select_from syntax to use to select via an odbc or other SQL based datasource
sql_select_from = "
select * from (
select a.*, c.filename as image_name, c.uri as image_uri
from dh_timeseries as a
left outer join field_data_field_image as b
on (
b.entity_id = a.tid
and b.entity_type = 'dh_timeseries'
)
left outer join file_managed as c
on (
c.fid = b.field_image_fid
)
) as dh_timeseries
",
#' @return get_id the id of this entity alias to remote pkid, subclassed as function
get_id = function() {
return(self$tid)
},
#' @param site URL of some RESTful repository
#' @param config list of attributes to set, see also: to_list() for format
#' @param load_remote automatically query REST data source for matches?
#' @return object instance
initialize = function(datasource = NULL, config = list(), load_remote = FALSE) {
# a config template can be generated by using the to_list() method
# of a blank object
# todo: some of this can be handled by the RomDataSource?
stopifnot(class(datasource)[[1]] == "RomDataSource")
self$datasource <- datasource
config_cols <- names(config)
if (is.element("varkey", config_cols)) {
if (!is.null(self$datasource)) {
message(paste("getting varid for", config$varkey))
vardef = self$datasource$get_vardef(config$varkey)
config$varid = vardef$hydroid
message(paste(" varid =", config$varid))
# eliminate this since if passed raw to rest will cause problems
config$varkey <- NULL
}
}
# if requested, we try to load
# only the last one returned will be sent back to user if multiple
if (load_remote) {
ts <- self$datasource$get_ts(config, 'list', TRUE, self)
# merge config with ts
#message("Found")
if (!is.logical(ts)) {
config <- ts
}
}
self$from_list(config)
},
#' @param config list of attributes to set, see also: to_list() for format
#' @return NULL
from_list = function(config) {
for (i in names(config)) {
if (i == "tid") {
self$tid = as.integer(as.character(config$tid))
} else if (i == "varid") {
self$varid = as.integer(as.character(config$varid))
} else if (i == "entity_type") {
self$entity_type = config$entity_type
} else if (i == "featureid") {
self$featureid = as.integer(as.character(config$featureid))
} else if (i == "tstime") {
self$tstime = as.integer(as.character(config$tstime))
} else if (i == "tsendtime") {
self$tsendtime = as.integer(as.character(config$tsendtime))
} else if (i == "tsvalue") {
self$tsvalue = config$tsvalue
} else if (i == "tscode") {
self$tscode = config$tscode
} else if (i == "tlid") {
self$tlid = as.integer(as.character(config$tlid))
} else if (i == "bundle") {
self$bundle = config$bundle
}
}
},
#' @return list of object attributes suitable for input to new() and from_list() methods
to_list = function() {
# returns as a list, which can be set and fed back to
# from_list() or new(config)
t_list <- list(
tid = as.integer(self$tid),
entity_type = self$entity_type,
varid = as.integer(self$varid),
featureid = as.integer(self$featureid),
tstime = as.integer(self$tstime),
tsendtime = as.integer(self$tsendtime),
tsvalue = self$tsvalue,
tscode = self$tscode
# todo
#modified = self$modified,
# todo:
#tlid = self$tlid,
# todo:
# uid = self$uid
# todo:
# bundle = self$bundle
)
return(t_list)
},
#' @param name attribute name
#' @param value attribute value
#' @param format type of data being sent (default, json, ...)
#' @return object instance
set_prop = function(name, value, format='default') {
# this should be at the base class, should not have to subclass
# @tbd: can this even be done on a local object field?
# it may not be necessary, we may only implement
# calls to set RomProperties linked to it?
# self$hair <- val
},
#' @param push_remote whether to automatically propagate changes to remote data source
#' @return boolean TRUE on success, FALSE on failure
save = function(push_remote=FALSE) {
# this should be at the base class, should not have to subclass
# @tbd: can this even be done on a local object field?
# data source responsibilities:
# - know how to format any entity for REST on this data source
# - know the site, token, and supporting functions if need be
# - support data retrieval functions, such as vardef
# object class responsibilities
# - know the required elements such as varid, featureid, entity_type
# fail if these required elements are not available
# it may not be necessary, we may only implement
# calls to set RomProperties linked to it?
# self$hair <- val
# do I have a varid? If not, get one, or fail.
if (push_remote) {
tid = self$datasource$post('dh_timeseries', 'tid', self$to_list())
message(paste("Post returned:", tid))
if (!is.logical(tid)) {
self$tid = tid
}
}
self$datasource$set_ts(self$to_list())
}
)
)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.