The senseBox is a do-it-yourself kit for stationary and mobile sensor stations. With senseBox you can make measurements, helping to answer a variety of scientific questions and to support Citizen Science Projects from the local to global scale. Data collected by senseBox can increase the measured density of various enviromental factors and can contribute to more precise statements regarding climate, pollution or traffic.
openSenseMap is the platform for the publishing of senseBox and other open sensor data. Each senseBox transmits its measurements directly to the map, where anyone can observe, analyze and download the data.
This is the point where this R-pacakge comes into play: The R-package senseBox provides access to the senseBox API and enables the user to download, analyse and visualise the data provided by registered senseBoxes.
With pacakges like ggplot2
or plotly
R is the perfect tool to
visualise data. In the next chapter you find a short introduction to the
basic usage of this R-package and some examples how to visualise the
data.
if(!require("devtools"))
install.packages("devtools")
devtools::install_github("JohannesFriedrich/senseBox")
Get some information about the senseBox project and list all senseBoxIds
library(senseBox)
## Loading required package: httr
stats <- get_senseBox_stats()
variable | value |
---|---|
Number of senseBoxes | 8615 |
Number of Measurements | 9775509322 |
Number of measurements in last minute | 5873 |
With the function get_senseBox_Ids()
you obtain all available senseBox
Ids and the name of the station.
Id_list <- get_senseBox_Ids()
senseBoxId | name |
---|---|
5386026e5f08822009b8b60d | CALIMERO |
538ee6a4a83415541576b777 | SenGIS Arbeitsgruppe - Uni Hohenheim |
5391be52a8341554157792e6 | LeKa Berlin |
539c00c2a83415541578eaf5 | IV Gummersbach |
539fec94a8341554157931d7 | The PaderWarrior Reloded |
53a0017aa834155415793281 | Alt-Lietzow |
You are just interested in senseBoxes, which collect data from “indoor”?
So use the function search_senseBox()
.
indoor <- search_senseBox(exposure = "indoor")
senseBoxId | exposure | name | createdAt | model | phenomena | unit | sensorIds | sensorType | long | lat | grouptag | updatedAt | weblink | lastMeasurementAt | description | height |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
54d79ea81b93e970075153f4 | indoor | Aasee-Station | 2015-02-08 17:36:40 | custom | UV , Beleuchtungsstärke, Luftdruck , rel. Luftfeuchte , Temperatur | UV-Index, lx , Pa , % , °C | 54d79ea81b93e970075153f6, 54d79ea81b93e970075153f7, 54d79ea81b93e970075153f8, 54d79ea81b93e970075153f9, 54d79ea81b93e970075153fa | GUVA-S12D, TSL2561 , BMP085 , DHT11 , DHT11 | 7.604985 | 51.94647 | NA | NA | NA | NA | NA | NA |
54e73244a807ade00f85f5bd | indoor | PhotonicNet | 2015-02-20 13:10:28 | custom | UV , Beleuchtungsstärke, Luftdruck , rel. Luftfeuchte , Temperatur | UV-Index, lx , Pa , % , °C | 54e73244a807ade00f85f5bf, 54e73244a807ade00f85f5c0, 54e73244a807ade00f85f5c1, 54e73244a807ade00f85f5c2, 54e73244a807ade00f85f5c3 | GUVA-S12D, TSL2561 , BMP085 , DHT11 , DHT11 | 9.635454 | 52.41255 | NA | NA | NA | NA | NA | NA |
54e7a5faa807ade00f868aab | indoor | fablab potsdam | 2016-08-28 16:54:36 | custom | UV , Beleuchtungsstärke, Luftdruck , rel. Luftfeuchte , Temperatur | UV-Index, lx , Pa , % , °C | 54e7a5faa807ade00f868aad, 54e7a5faa807ade00f868aae, 54e7a5faa807ade00f868aaf, 54e7a5faa807ade00f868ab0, 54e7a5faa807ade00f868ab1 | GUVA-S12D, TSL2561 , BMP085 , DHT11 , DHT11 | 13.080662 | 52.39649 | MakeLight | 2016-12-17 14:55:05 | NA | NA | NA | NA |
We chose one ID for the following examples
senseBoxId <- "592ca4b851d3460011ea2635"
location <- get_senseBox_location(senseBoxId)
library(leaflet)
library(htmltools)
leaflet(location) %>%
addProviderTiles(providers$OpenStreetMap) %>%
addTiles() %>%
addMarkers(~long, ~lat, popup = ~htmltools::htmlEscape(name))
Get some information about the senseBox sensors
sensor_info <- get_senseBox_sensor_info(senseBoxId)
name | phenomena | unit | sensorIds | sensorType |
---|---|---|---|---|
Leipziger65-Süd | PM10 , PM2.5 , Temperatur , rel. Luftfeuchte | µg/m³, µg/m³, °C , % | 592ca4b851d3460011ea2636, 592ca4b851d3460011ea2637, 592ca4b851d3460011ea2638, 592ca4b851d3460011ea2639 | SDS 011, SDS 011, DHT22 , DHT22 |
With the argument tidy = TRUE
a tidy data.frame will be produced:
sensor_info <- get_senseBox_sensor_info(senseBoxId, tidy = TRUE)
name | phenomena | unit | sensorIds | sensorType |
---|---|---|---|---|
Leipziger65-Süd | PM10 | µg/m³ | 592ca4b851d3460011ea2636 | SDS 011 |
Leipziger65-Süd | PM2.5 | µg/m³ | 592ca4b851d3460011ea2637 | SDS 011 |
Leipziger65-Süd | Temperatur | °C | 592ca4b851d3460011ea2638 | DHT22 |
Leipziger65-Süd | rel. Luftfeuchte | % | 592ca4b851d3460011ea2639 | DHT22 |
We can now download data from the senseBox, either from a specific sensorId or from all sensors within the sensBox. In the following we are downloading all available sensors.
data_all <- get_senseBox_data(senseBoxId)
When you are interested in just a selection of sensors, just submit the
sensorIds to the function get_senseBox_data()
.
sensor_ids <- get_senseBox_sensor_Ids(senseBoxId)
data_sel <- get_senseBox_data(senseBoxId,
sensorId = sensor_ids$sensorIds[1:2])
When using the above code, by default, the data from the last 48 h will
be downloaded. You can donwload up to 10,000 records and sepcify the
date of the record. The maximum time frame for downloading data is back
to one month from now. Use the argument fromDate
and toDate
to
specify the desired time frame. Note that in contrast to the code above,
all sensors from the senseBox are requested (by default) because
argument sensorId
is not set.
data_timeframe <- get_senseBox_data(senseBoxId,
fromDate = "2017-11-11 11:11:11",
toDate = "2017-11-12 11:11:11")
Visualising the results from all sensors is one of the main aims and we
recommend using the R-package ggplot2
. We provide a sample code
next and you just have to change the data executed in the function
melt()
.
library(ggplot2)
library(reshape2)
library(scales)
data_melt <- melt(data_timeframe, id.vars = c("createdAt", "value"))
ggplot(data_melt, aes(x = createdAt, y = value, colour = L2)) +
geom_line() +
scale_x_datetime(labels = date_format("%H:%M", tz = Sys.timezone())) +
facet_wrap(~L2, scales = "free") +
theme(legend.position = "bottom",
legend.title = element_blank())
Receiving data with get_senseBox_data()
is limited to 10.000 data
points. But every day all measured sensor data are stored in the
senseBox archive. With the function get_senseBox_archive()
the zip
file from a specific senseBox for a date can be downloaded. You have to
unzip the folder by yourself and every sensor data is stored in a csv
file.
get_senseBox_archive(senseBoxId,
date = "2018-07-31")
infos <- get_senseBox_info(Id_list$senseBoxId, parallel = TRUE)
library(dplyr)
library(tidyr)
infos %>%
select(name, phenomena) %>%
unnest() %>%
count(phenomena) %>%
arrange(desc(n)) %>%
top_n(10, n) %>%
ggplot() +
geom_histogram(aes(x = phenomena, y = n), stat = "identity") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
## Warning: `cols` is now required when using unnest().
## Please use `cols = c(phenomena)`
## Warning: Ignoring unknown parameters: binwidth, bins, pad
infos %>%
group_by(exposure, grouptag) %>%
summarise(n = n()) %>%
arrange(desc(n)) %>%
na.omit() %>%
top_n(5, n) %>%
ggplot() +
geom_bar(aes(x = grouptag, y = n, fill = exposure), stat = "identity") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
## `summarise()` has grouped output by 'exposure'. You can override using the `.groups` argument.
library(lubridate)
infos %>%
mutate(year = year(createdAt),
month = month(createdAt),
day = day(createdAt)) %>%
group_by(year, exposure) %>%
summarise(n = n()) %>%
arrange(desc(year)) %>%
ggplot() +
geom_bar(aes(x = year, y = n, fill = exposure), stat = "identity")
## `summarise()` has grouped output by 'year'. You can override using the `.groups` argument.
This site offers a list of all available senseBoxes (27-01-2020). You can search for any keyword you are interested in.