|
|
|
---
|
|
|
|
output: rmarkdown::github_document
|
|
|
|
editor_options:
|
|
|
|
chunk_output_type: inline
|
|
|
|
---
|
|
|
|
```{r pkg-knitr-opts, include=FALSE}
|
|
|
|
knitr::opts_chunk$set(collapse=TRUE, fig.retina=2, message=FALSE, warning=FALSE)
|
|
|
|
options(width=120)
|
|
|
|
```
|
|
|
|
|
|
|
|
[![Travis-CI Build Status](https://travis-ci.org/hrbrmstr/deere.svg?branch=master)](https://travis-ci.org/hrbrmstr/deere)
|
|
|
|
[![Coverage Status](https://codecov.io/gh/hrbrmstr/deere/branch/master/graph/badge.svg)](https://codecov.io/gh/hrbrmstr/deere)
|
|
|
|
[![CRAN_Status_Badge](http://www.r-pkg.org/badges/version/deere)](https://cran.r-project.org/package=deere)
|
|
|
|
|
|
|
|
# deere
|
|
|
|
|
|
|
|
Catchall Functions for All Things 'John Deere'
|
|
|
|
|
|
|
|
## Description
|
|
|
|
|
|
|
|
Initially a convenience package to access 'John Deere' 'MowerPlus' databases from 'iOS' backups but perpaps will be something more all-encompassing.
|
|
|
|
|
|
|
|
Ref:
|
|
|
|
|
|
|
|
- <https://rud.is/b/2019/06/02/trawling-through-ios-backups-for-treasure-a-k-a-how-to-fish-for-target-files-in-ios-backups-with-r/>
|
|
|
|
- <https://rud.is/b/2019/06/09/wrapping-up-exploration-of-john-deeres-mowerplus-database/>
|
|
|
|
|
|
|
|
## What's Inside The Tin
|
|
|
|
|
|
|
|
The following functions are implemented:
|
|
|
|
|
|
|
|
- `from_coredata_ts`: Convert timestampes from Apple "CoreData" format to something usable
|
|
|
|
- `list_ios_backups`: List iOS backups available on this system
|
|
|
|
- `platform_ios_backup_dir`: List iOS backups available on this system
|
|
|
|
- `src_mowerplus`: Find and sync a copy of the latest MowerPlus database file from an iOS backup
|
|
|
|
|
|
|
|
## Installation
|
|
|
|
|
|
|
|
```{r install-ex, eval=FALSE}
|
|
|
|
devtools::install_git("https://git.sr.ht/~hrbrmstr/deere.git")
|
|
|
|
# or
|
|
|
|
devtools::install_git("https://git.rud.is/hrbrmstr/deere.git")
|
|
|
|
# or
|
|
|
|
devtools::install_gitlab("hrbrmstr/deere")
|
|
|
|
# or
|
|
|
|
devtools::install_bitbucket("hrbrmstr/deere")
|
|
|
|
# or
|
|
|
|
devtools::install_github("hrbrmstr/deere")
|
|
|
|
```
|
|
|
|
|
|
|
|
## Usage
|
|
|
|
|
|
|
|
```{r lib-ex}
|
|
|
|
library(deere)
|
|
|
|
library(hrbrthemes)
|
|
|
|
library(tidyverse)
|
|
|
|
|
|
|
|
# current version
|
|
|
|
packageVersion("deere")
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
### Sample from the latest mow
|
|
|
|
|
|
|
|
```{r mow, cache=TRUE}
|
|
|
|
list_ios_backups()
|
|
|
|
|
|
|
|
mow_db <- src_mowerplus()
|
|
|
|
|
|
|
|
mow_db
|
|
|
|
|
|
|
|
glimpse(tbl(mow_db, "ZMOWER"))
|
|
|
|
|
|
|
|
glimpse(tbl(mow_db, "ZACTIVITY"))
|
|
|
|
|
|
|
|
tbl(mow_db, "ZACTIVITY")%>%
|
|
|
|
collect() -> activity
|
|
|
|
|
|
|
|
activity %>%
|
|
|
|
select(
|
|
|
|
mow_date = ZCREATEDAT,
|
|
|
|
area_covered = ZAREACOVERED,
|
|
|
|
avg_speed = ZAVERAGESPEED,
|
|
|
|
distance = ZDISTANCEMOWED,
|
|
|
|
duration = ZMOWINGTIME
|
|
|
|
) %>%
|
|
|
|
arrange(mow_date) %>%
|
|
|
|
mutate(
|
|
|
|
duration = duration / 60 / 60, # hours
|
|
|
|
mow_date = format(from_coredata_ts(mow_date), "%b %d"), # factors make better bars
|
|
|
|
mow_date = factor(mow_date, levels = unique(mow_date)) # when there are just 2-of-em
|
|
|
|
) %>%
|
|
|
|
gather(measure, value, -mow_date) %>%
|
|
|
|
ggplot(aes(mow_date, value)) +
|
|
|
|
geom_col(aes(fill = measure), width = 0.5, show.legend = FALSE) +
|
|
|
|
scale_y_comma() +
|
|
|
|
scale_fill_ipsum() +
|
|
|
|
facet_wrap(~measure, scales = "free") +
|
|
|
|
theme_ipsum_rc(grid="Y")
|
|
|
|
|
|
|
|
zloc <- tbl(mow_db, "ZMOWLOCATION")
|
|
|
|
|
|
|
|
|
|
|
|
zloc %>%
|
|
|
|
select(
|
|
|
|
id = ZSESSION,
|
|
|
|
zorder = ZORDER,
|
|
|
|
lat = ZLATITUDE,
|
|
|
|
lng = ZLONGITUDE,
|
|
|
|
speed = ZSPEED,
|
|
|
|
ts = ZTIMESTAMP
|
|
|
|
) %>%
|
|
|
|
collect() %>%
|
|
|
|
mutate(
|
|
|
|
id = factor(id),
|
|
|
|
ts = from_coredata_ts(ts)
|
|
|
|
) -> sessions
|
|
|
|
|
|
|
|
ggplot(sessions, aes(id, speed)) +
|
|
|
|
ggbeeswarm::geom_quasirandom(
|
|
|
|
aes(fill = id), show.legend = FALSE,
|
|
|
|
shape = 21, size = 2, color = "white", stroke = 0.75
|
|
|
|
) +
|
|
|
|
scale_fill_ipsum() +
|
|
|
|
labs(x = "Mowing Session", y = "MPH", title = "Mowing Speed Comparison (mph)") +
|
|
|
|
theme_ipsum_rc(grid="Y")
|
|
|
|
|
|
|
|
arrange(sessions, ts) %>%
|
|
|
|
ggplot(aes(lng, lat)) +
|
|
|
|
geom_path(
|
|
|
|
aes(color = id, group = id), show.legend = FALSE,
|
|
|
|
size = 1, alpha = 1/2
|
|
|
|
) +
|
|
|
|
scale_color_ipsum() +
|
|
|
|
coord_quickmap() +
|
|
|
|
facet_wrap(~id) +
|
|
|
|
labs(title = "Mowing Path Comparison") +
|
|
|
|
theme_ipsum_rc(grid="Y") +
|
|
|
|
ggthemes::theme_map()
|
|
|
|
```
|
|
|
|
|
|
|
|
## deere Metrics
|
|
|
|
|
|
|
|
```{r cloc, echo=FALSE}
|
|
|
|
cloc::cloc_pkg_md()
|
|
|
|
```
|
|
|
|
|
|
|
|
## Code of Conduct
|
|
|
|
|
|
|
|
Please note that this project is released with a [Contributor Code of Conduct](CONDUCT.md).
|
|
|
|
By participating in this project you agree to abide by its terms.
|