This is how to insert new wind data from ATMOS-22 sonic anemometers into the database. Click “Code” at the top of this page to download an rmarkdown version of this file!

Prepare data

Make one data frame for each “instrument deployment” action, i.e. data from one point without shifts in the x, y, or z location. There should be a Timestamp column with datetime formatted as YYYY-MM-DD HH:MM:SS, and one column for each of the variables measured.

Define a custom function to read in Excel output from Zentra Utility without extraneous rows:

read_em50_wind <- function(filename, outfile = NULL){
  windcolnames <- c("Timestamp", 
                    "Wind_direction_degree", 
                    "wind_speed_metersPerSecond", 
                    "gust_speed_metersPerSecond", 
                    "anemometer_temp_degreeC")
  df <- readxl::read_xlsx(filename, 
                          sheet = "Processed Records", 
                          skip = 3, 
                          col_names = windcolnames,
                          na = "#N/A",
                          col_types = c("date", rep("numeric", 4)))
  if(!is.null(outfile)){
    write.csv(df, file = paste0(outfile, ".csv"), row.names = FALSE)
  }
  return(df)
}

Then use the function to read in new files to be uploaded:

files <- list.files("../../Delmarva/data/wind", full.names = TRUE)
files
[1] "../../Delmarva/data/wind/EM44493 22Jul18-1125.xlsx"
[2] "../../Delmarva/data/wind/EM44493 30Jun18-1307.xlsx"
[3] "../../Delmarva/data/wind/EM44505 22Jul18-1246.xlsx"
[4] "../../Delmarva/data/wind/EM44505 30Jun18-0931.xlsx"

These files should have a column “Timestamp” with properly formatted dates (YYYY-MM-DD HH:MM:SS) and one column for each variable measured.

Timestamp Wind_direction_degree wind_speed_metersPerSecond gust_speed_metersPerSecond anemometer_temp_degreeC
2018-06-23 21:45:00 56 0.07 0.2 -39.8
2018-06-23 21:50:00 54 0.09 0.2 -39.8
2018-06-23 21:55:00 57 0.08 0.2 -39.8
2018-06-23 22:00:00 59 0.08 0.2 -39.8
2018-06-23 22:05:00 61 0.08 0.2 -39.8
2018-06-23 22:10:00 67 0.07 0.2 -39.8

Make sure there are no NA data values. Your data is not ready to upload if it contains NAs!

names(nd_30jun)[-1] %>%
  purrr::map_lgl(function(x) any(is.na(nd_30jun[[x]])))
[1] FALSE  TRUE  TRUE FALSE
names(nd_18jul)[-1] %>%
  purrr::map_lgl(function(x) any(is.na(nd_18jul[[x]])))
[1] FALSE FALSE FALSE FALSE

Upload

Then load rodm2 and connect to the database

devtools::install_github("khondula/rodm2")
library(rodm2)

vars list

Make a list with the necessary information about each variable with the following format:

list("Variable1 Name" = list(column = "ColumnName", units = "Units Name"),
     "Variable2 Name" = list(column = "ColumnName", units = "Units Name"))

If the column name is the exact name of the variable from the controlled vocabulary (i.e. with spaces and correct capitalization), column does not need to be specified. If there are columns in your data that have data quality codes or censor codes, those should be specified here as qualitycodecol and censorcodecol respectively.

Variable names and units names need to be from the controlled vocabularies. To see these options, use the get_cv_terms() function.

get_cv_terms("variablename")
get_cv_terms("units")
vars_list <- list(
  'Wind direction' = list(column = 'Wind_direction_degree', units = 'Degree'),
  'Wind speed' = list(column = 'wind_speed_metersPerSecond', units = 'Meter per Second'),
  'Wind gust speed' = list(column = 'gust_speed_metersPerSecond', units = 'Meter per Second')
)

upload ts function

Use db_insert_results_ts() to upload the data. The arguments actionby and equipment_name are optional. For processed data, specify a value for processinglevel (the default is “Raw data”).

db_insert_results_ts(db = db, # database connecton
                     datavalues = nd_18jul, # data frame of time series data
                     method = "SonicAnemometer", 
                     site_code = "ND", 
                     variables = vars_list, 
                     sampledmedium = "Air", # from medium controlled vocabulary
                     actionby = "Kelly", # optional
                     equipment_name = "Wind2" # optional
                     )

Helper functions

The method and site code will be added to the database if they do not already exist. If the values supplied for actionby or equipment_name do not already exist in the database, you will also need to supply the required arguments to db_descrbie_person() or db_describe_equipment().

If you want to see if a site code exists in the database already, use check_samplingfeaturecodes to returns the names of any sites NOT in the database compared to a given vector, or get_site_names_like() for approximate string matching for sites that ARE in the database.

check_samplingfeaturecodes(new_codes = "ND", db = db)
[1] new_codes in_db    
<0 rows> (or 0-length row.names)
get_site_names_like(x = "QB well", db = db)
[1] "QB Wetland Well - Shallow" "QB Wetland Well - Deep"   
[3] "QB Wetland Outlet"        

To see the current methods, people, or equipment in the database, use db_get_%() functions:

db_get_variables(db)
                 variablenamecv
1              delta-18O of H2O
2                delta-D of H2O
3      Volumetric water content
4                   Temperature
5  Bulk electrical conductivity
6                       Methane
7                Carbon dioxide
8                    Wind speed
9               Wind gust speed
10               Wind direction
LS0tCnRpdGxlOiAiSW5zZXJ0IHNvbmljIGFuZW1vbWV0ZXIgZGF0YSIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6CiAgICBkZl9wcmludDogcGFnZWQKZWRpdG9yX29wdGlvbnM6CiAgY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZQotLS0KClRoaXMgaXMgaG93IHRvIGluc2VydCBuZXcgd2luZCBkYXRhIGZyb20gQVRNT1MtMjIgc29uaWMgYW5lbW9tZXRlcnMgaW50byB0aGUgZGF0YWJhc2UuIENsaWNrICJDb2RlIiBhdCB0aGUgdG9wIG9mIHRoaXMgcGFnZSB0byBkb3dubG9hZCBhbiBybWFya2Rvd24gdmVyc2lvbiBvZiB0aGlzIGZpbGUhIAoKIyBQcmVwYXJlIGRhdGEKCk1ha2Ugb25lIGRhdGEgZnJhbWUgZm9yIGVhY2ggImluc3RydW1lbnQgZGVwbG95bWVudCIgYWN0aW9uLCBpLmUuIGRhdGEgZnJvbSBvbmUgcG9pbnQgd2l0aG91dCBzaGlmdHMgaW4gdGhlIHgsIHksIG9yIHogbG9jYXRpb24uIFRoZXJlIHNob3VsZCBiZSBhIFRpbWVzdGFtcCBjb2x1bW4gd2l0aCBkYXRldGltZSBmb3JtYXR0ZWQgYXMgWVlZWS1NTS1ERCBISDpNTTpTUywgYW5kIG9uZSBjb2x1bW4gZm9yIGVhY2ggb2YgdGhlIHZhcmlhYmxlcyBtZWFzdXJlZC4gCgpEZWZpbmUgYSBjdXN0b20gZnVuY3Rpb24gdG8gcmVhZCBpbiBFeGNlbCBvdXRwdXQgZnJvbSBaZW50cmEgVXRpbGl0eSB3aXRob3V0IGV4dHJhbmVvdXMgcm93czoKCmBgYHtyIHJlYWRfZW01MH0KcmVhZF9lbTUwX3dpbmQgPC0gZnVuY3Rpb24oZmlsZW5hbWUsIG91dGZpbGUgPSBOVUxMKXsKICB3aW5kY29sbmFtZXMgPC0gYygiVGltZXN0YW1wIiwgCiAgICAgICAgICAgICAgICAgICAgIldpbmRfZGlyZWN0aW9uX2RlZ3JlZSIsIAogICAgICAgICAgICAgICAgICAgICJ3aW5kX3NwZWVkX21ldGVyc1BlclNlY29uZCIsIAogICAgICAgICAgICAgICAgICAgICJndXN0X3NwZWVkX21ldGVyc1BlclNlY29uZCIsIAogICAgICAgICAgICAgICAgICAgICJhbmVtb21ldGVyX3RlbXBfZGVncmVlQyIpCiAgZGYgPC0gcmVhZHhsOjpyZWFkX3hsc3goZmlsZW5hbWUsIAogICAgICAgICAgICAgICAgICAgICAgICAgIHNoZWV0ID0gIlByb2Nlc3NlZCBSZWNvcmRzIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgc2tpcCA9IDMsIAogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbF9uYW1lcyA9IHdpbmRjb2xuYW1lcywKICAgICAgICAgICAgICAgICAgICAgICAgICBuYSA9ICIjTi9BIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xfdHlwZXMgPSBjKCJkYXRlIiwgcmVwKCJudW1lcmljIiwgNCkpKQogIGlmKCFpcy5udWxsKG91dGZpbGUpKXsKICAgIHdyaXRlLmNzdihkZiwgZmlsZSA9IHBhc3RlMChvdXRmaWxlLCAiLmNzdiIpLCByb3cubmFtZXMgPSBGQUxTRSkKICB9CiAgcmV0dXJuKGRmKQp9CmBgYAoKVGhlbiB1c2UgdGhlIGZ1bmN0aW9uIHRvIHJlYWQgaW4gbmV3IGZpbGVzIHRvIGJlIHVwbG9hZGVkOgoKYGBge3J9CmZpbGVzIDwtIGxpc3QuZmlsZXMoIi4uLy4uL0RlbG1hcnZhL2RhdGEvd2luZCIsIGZ1bGwubmFtZXMgPSBUUlVFKQpgYGAKCmBgYHtyfQpmaWxlcwpgYGAKCmBgYHtyfQpuZF8zMGp1biA8LSByZWFkX2VtNTBfd2luZChmaWxlbmFtZSA9IGZpbGVzWzRdKQpuZF8xOGp1bCA8LSByZWFkX2VtNTBfd2luZChmaWxlbmFtZSA9IGZpbGVzWzNdKQpgYGAKClRoZXNlIGZpbGVzIHNob3VsZCBoYXZlIGEgY29sdW1uICJUaW1lc3RhbXAiIHdpdGggcHJvcGVybHkgZm9ybWF0dGVkIGRhdGVzIChZWVlZLU1NLUREIEhIOk1NOlNTKSBhbmQgb25lIGNvbHVtbiBmb3IgZWFjaCB2YXJpYWJsZSBtZWFzdXJlZC4gCgpgYGB7ciBlY2hvPUZBTFNFLCByZXN1bHRzPSdhc2lzJ30KaGVhZChuZF8zMGp1bikgJT4lIGtuaXRyOjprYWJsZSgpCmBgYAoKTWFrZSBzdXJlIHRoZXJlIGFyZSBubyBOQSBkYXRhIHZhbHVlcy4gWW91ciBkYXRhIGlzIG5vdCByZWFkeSB0byB1cGxvYWQgaWYgaXQgY29udGFpbnMgTkFzIQoKYGBge3J9Cm5hbWVzKG5kXzMwanVuKVstMV0gJT4lCiAgcHVycnI6Om1hcF9sZ2woZnVuY3Rpb24oeCkgYW55KGlzLm5hKG5kXzMwanVuW1t4XV0pKSkKCm5hbWVzKG5kXzE4anVsKVstMV0gJT4lCiAgcHVycnI6Om1hcF9sZ2woZnVuY3Rpb24oeCkgYW55KGlzLm5hKG5kXzE4anVsW1t4XV0pKSkKYGBgCgoKIyBVcGxvYWQKClRoZW4gbG9hZCBgcm9kbTJgIGFuZCBjb25uZWN0IHRvIHRoZSBkYXRhYmFzZQpgYGB7ciwgbWVzc2FnZT1GQUxTRX0KZGV2dG9vbHM6Omluc3RhbGxfZ2l0aHViKCJraG9uZHVsYS9yb2RtMiIpCmxpYnJhcnkocm9kbTIpCmBgYAoKYGBge3IsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGNvbW1lbnQ9TlVMTH0KbGlicmFyeShSUG9zdGdyZVNRTCkKcGFzc3dvcmQgPC0gc2NhbigiLnBncGFzcyIsIHdoYXQ9IiIpCmRiIDwtIGRiQ29ubmVjdChQb3N0Z3JlU1FMKCksIAogICAgICAgICAgICAgICAgaG9zdCA9ICJzZXN5bmMtcG9zdGdpczAxLnJlc2VhcmNoLnNlc3luYy5vcmciLAogICAgICAgICAgICAgICAgZGJuYW1lID0gImNob3B0YW5rIiwgCiAgICAgICAgICAgICAgICB1c2VyID0gInBhbG1lcmdyb3VwIiwKICAgICAgICAgICAgICAgIHBhc3N3b3JkID0gcGFzc3dvcmQpCmBgYAoKCj4gKip2YXJzIGxpc3QqKgoKTWFrZSBhIGxpc3Qgd2l0aCB0aGUgbmVjZXNzYXJ5IGluZm9ybWF0aW9uIGFib3V0IGVhY2ggdmFyaWFibGUgd2l0aCB0aGUgZm9sbG93aW5nIGZvcm1hdDoKCmBgYApsaXN0KCJWYXJpYWJsZTEgTmFtZSIgPSBsaXN0KGNvbHVtbiA9ICJDb2x1bW5OYW1lIiwgdW5pdHMgPSAiVW5pdHMgTmFtZSIpLAogICAgICJWYXJpYWJsZTIgTmFtZSIgPSBsaXN0KGNvbHVtbiA9ICJDb2x1bW5OYW1lIiwgdW5pdHMgPSAiVW5pdHMgTmFtZSIpKQpgYGAKCklmIHRoZSBjb2x1bW4gbmFtZSBpcyB0aGUgZXhhY3QgbmFtZSBvZiB0aGUgdmFyaWFibGUgZnJvbSB0aGUgY29udHJvbGxlZCB2b2NhYnVsYXJ5IChpLmUuIHdpdGggc3BhY2VzIGFuZCBjb3JyZWN0IGNhcGl0YWxpemF0aW9uKSwgYGNvbHVtbmAgZG9lcyBub3QgbmVlZCB0byBiZSBzcGVjaWZpZWQuIElmIHRoZXJlIGFyZSBjb2x1bW5zIGluIHlvdXIgZGF0YSB0aGF0IGhhdmUgZGF0YSBxdWFsaXR5IGNvZGVzIG9yIGNlbnNvciBjb2RlcywgdGhvc2Ugc2hvdWxkIGJlIHNwZWNpZmllZCBoZXJlIGFzIGBxdWFsaXR5Y29kZWNvbGAgYW5kIGBjZW5zb3Jjb2RlY29sYCByZXNwZWN0aXZlbHkuIAoKVmFyaWFibGUgbmFtZXMgYW5kIHVuaXRzIG5hbWVzIG5lZWQgdG8gYmUgZnJvbSB0aGUgY29udHJvbGxlZCB2b2NhYnVsYXJpZXMuIFRvIHNlZSB0aGVzZSBvcHRpb25zLCB1c2UgdGhlIGBnZXRfY3ZfdGVybXMoKWAgZnVuY3Rpb24uIAoKYGBge3IsIGV2YWw9RkFMU0V9CmdldF9jdl90ZXJtcygidmFyaWFibGVuYW1lIikKZ2V0X2N2X3Rlcm1zKCJ1bml0cyIpCmBgYAoKYGBge3J9CnZhcnNfbGlzdCA8LSBsaXN0KAogICdXaW5kIGRpcmVjdGlvbicgPSBsaXN0KGNvbHVtbiA9ICdXaW5kX2RpcmVjdGlvbl9kZWdyZWUnLCB1bml0cyA9ICdEZWdyZWUnKSwKICAnV2luZCBzcGVlZCcgPSBsaXN0KGNvbHVtbiA9ICd3aW5kX3NwZWVkX21ldGVyc1BlclNlY29uZCcsIHVuaXRzID0gJ01ldGVyIHBlciBTZWNvbmQnKSwKICAnV2luZCBndXN0IHNwZWVkJyA9IGxpc3QoY29sdW1uID0gJ2d1c3Rfc3BlZWRfbWV0ZXJzUGVyU2Vjb25kJywgdW5pdHMgPSAnTWV0ZXIgcGVyIFNlY29uZCcpCikKYGBgCgo+ICoqdXBsb2FkIHRzIGZ1bmN0aW9uKioKClVzZSBgZGJfaW5zZXJ0X3Jlc3VsdHNfdHMoKWAgdG8gdXBsb2FkIHRoZSBkYXRhLiBUaGUgYXJndW1lbnRzIGBhY3Rpb25ieWAgYW5kIGBlcXVpcG1lbnRfbmFtZWAgYXJlIG9wdGlvbmFsLiBGb3IgcHJvY2Vzc2VkIGRhdGEsIHNwZWNpZnkgYSB2YWx1ZSBmb3IgYHByb2Nlc3NpbmdsZXZlbGAgKHRoZSBkZWZhdWx0IGlzICJSYXcgZGF0YSIpLiAKCmBgYHtyLCBldmFsID0gRkFMU0V9CmRiX2luc2VydF9yZXN1bHRzX3RzKGRiID0gZGIsICMgZGF0YWJhc2UgY29ubmVjdG9uCiAgICAgICAgICAgICAgICAgICAgIGRhdGF2YWx1ZXMgPSBuZF8xOGp1bCwgIyBkYXRhIGZyYW1lIG9mIHRpbWUgc2VyaWVzIGRhdGEKICAgICAgICAgICAgICAgICAgICAgbWV0aG9kID0gIlNvbmljQW5lbW9tZXRlciIsIAogICAgICAgICAgICAgICAgICAgICBzaXRlX2NvZGUgPSAiTkQiLCAKICAgICAgICAgICAgICAgICAgICAgdmFyaWFibGVzID0gdmFyc19saXN0LCAKICAgICAgICAgICAgICAgICAgICAgc2FtcGxlZG1lZGl1bSA9ICJBaXIiLCAjIGZyb20gbWVkaXVtIGNvbnRyb2xsZWQgdm9jYWJ1bGFyeQogICAgICAgICAgICAgICAgICAgICBhY3Rpb25ieSA9ICJLZWxseSIsICMgb3B0aW9uYWwKICAgICAgICAgICAgICAgICAgICAgZXF1aXBtZW50X25hbWUgPSAiV2luZDIiICMgb3B0aW9uYWwKICAgICAgICAgICAgICAgICAgICAgKQpgYGAKCiMjIyBIZWxwZXIgZnVuY3Rpb25zCgpUaGUgbWV0aG9kIGFuZCBzaXRlIGNvZGUgd2lsbCBiZSBhZGRlZCB0byB0aGUgZGF0YWJhc2UgaWYgdGhleSBkbyBub3QgYWxyZWFkeSBleGlzdC4gSWYgdGhlIHZhbHVlcyBzdXBwbGllZCBmb3IgYGFjdGlvbmJ5YCBvciBgZXF1aXBtZW50X25hbWVgIGRvIG5vdCBhbHJlYWR5IGV4aXN0IGluIHRoZSBkYXRhYmFzZSwgeW91IHdpbGwgYWxzbyBuZWVkIHRvIHN1cHBseSB0aGUgcmVxdWlyZWQgYXJndW1lbnRzIHRvIGBkYl9kZXNjcmJpZV9wZXJzb24oKWAgb3IgYGRiX2Rlc2NyaWJlX2VxdWlwbWVudCgpYC4gCgpJZiB5b3Ugd2FudCB0byBzZWUgaWYgYSBzaXRlIGNvZGUgZXhpc3RzIGluIHRoZSBkYXRhYmFzZSBhbHJlYWR5LCB1c2UgYGNoZWNrX3NhbXBsaW5nZmVhdHVyZWNvZGVzYCB0byByZXR1cm5zIHRoZSBuYW1lcyBvZiBhbnkgc2l0ZXMgTk9UIGluIHRoZSBkYXRhYmFzZSBjb21wYXJlZCB0byBhIGdpdmVuIHZlY3Rvciwgb3IgYGdldF9zaXRlX25hbWVzX2xpa2UoKWAgZm9yIGFwcHJveGltYXRlIHN0cmluZyBtYXRjaGluZyBmb3Igc2l0ZXMgdGhhdCBBUkUgaW4gdGhlIGRhdGFiYXNlLiAKCmBgYHtyLCB3YXJuaW5nPUZBTFNFfQpjaGVja19zYW1wbGluZ2ZlYXR1cmVjb2RlcyhuZXdfY29kZXMgPSAiTkQiLCBkYiA9IGRiKQpgYGAKCmBgYHtyLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQpnZXRfc2l0ZV9uYW1lc19saWtlKHggPSAiUUIgd2VsbCIsIGRiID0gZGIpCmBgYAoKVG8gc2VlIHRoZSBjdXJyZW50IG1ldGhvZHMsIHBlb3BsZSwgb3IgZXF1aXBtZW50IGluIHRoZSBkYXRhYmFzZSwgdXNlIGBkYl9nZXRfJSgpYCBmdW5jdGlvbnM6CgpgYGB7cn0KZGJfZ2V0X2VxdWlwbWVudChkYikKZGJfZ2V0X3Blb3BsZShkYikKZGJfZ2V0X21ldGhvZHMoZGIpCmBgYAoK