I have a weather station that sends data out periodically and want to make an API with plumber to receive and save the JSON data. My script is
# plumber.R
library(tidyverse)
library(lubridate)
#' @post /station
#' @serializer json
#' @param wind_direction_raw
#' @param rain_amount_raw
#' @param timestamp
#' @param elapsed_time
#' @param wind_speed_raw
#' @param message_id
function(req, wind_direction_raw, rain_amount_raw, timestamp,
elapsed_time, wind_speed_raw, message_id){
new_data <- tibble("wind_direction_raw" = wind_direction_raw,
"rain_amount_raw" = rain_amount_raw,
"wind_speed_raw" = wind_speed_raw,
"timestamp" = ymd_hms(paste(timestamp[1:6], collapse="="), tz = "UTC"),
"elapsed_time" = elapsed_time,
"message_id" = message_id)
write_path <- paste0("/home/pi/weather_station/data/weather_data_",
Sys.Date(), ".csv")
readr::write_csv(new_data, write_path, append=TRUE)
When I open an R
session and type
> library(plumber)
> weather_service <- pr('/home/pi/weather_station/weather_api/receive_json.R')
> pr_run(weather_service, port=9494, host='192.168.1.151')
and then on another computer send some json with curl
with
curl -X POST -H "Content-Type: application/json" --data '{"elapsed_time": 6245, "timestamp": "[2020, 7, 26, 12, 2, 21, 6, 208]", "wind_direction_raw": 108, "wind_speed_raw": 5, "message_id": 666, "rain_amount_raw": "0"}' http://192.168.1.151:9494/station
it works fine. Same with my actual weather station.
However when I use this systemd service file
[Unit]
Description=Plumber API
[Service]
ExecStart=/usr/bin/Rscript -e "library(plumber); pr_run(pr('/home/pi/weather_station/weather_api/receive_json.R'), port=9494, host='192.168.1.151')"
Restart= always
RestartSec=60
SyslogIdentifier=WeatherAPI
[Install]
WantedBy=multi-user.target
Neither the weather station or my curl
example can send data. It seems to hang in the middle of the send process, since the curl
process hangs and never finishes.
sudo systemctl status
looks good with
Feb 03 17:24:25 gatesPi4 systemd[1]: Started Plumber API.
Feb 03 17:24:29 gatesPi4 WeatherAPI[14465]: ── Attaching packages ─────────────────────────────────────── tidyverse 1.3.0 ──
Feb 03 17:24:29 gatesPi4 WeatherAPI[14465]: ✔ ggplot2 3.3.2 ✔ purrr 0.3.4
Feb 03 17:24:29 gatesPi4 WeatherAPI[14465]: ✔ tibble 3.0.1 ✔ dplyr 1.0.0
Feb 03 17:24:29 gatesPi4 WeatherAPI[14465]: ✔ tidyr 1.1.0 ✔ stringr 1.4.0
Feb 03 17:24:29 gatesPi4 WeatherAPI[14465]: ✔ readr 1.3.1 ✔ forcats 0.5.0
Feb 03 17:24:30 gatesPi4 WeatherAPI[14465]: ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
Feb 03 17:24:30 gatesPi4 WeatherAPI[14465]: ✖ tidyr::extract() masks magrittr::extract()
Feb 03 17:24:30 gatesPi4 WeatherAPI[14465]: ✖ dplyr::filter() masks stats::filter()
Feb 03 17:24:30 gatesPi4 WeatherAPI[14465]: ✖ dplyr::lag() masks stats::lag()
Feb 03 17:24:30 gatesPi4 WeatherAPI[14465]: ✖ purrr::set_names() masks magrittr::set_names()
Feb 03 17:24:30 gatesPi4 WeatherAPI[14465]: Attaching package: ‘lubridate’
Feb 03 17:24:30 gatesPi4 WeatherAPI[14465]: The following objects are masked from ‘package:base’:
Feb 03 17:24:30 gatesPi4 WeatherAPI[14465]: date, intersect, setdiff, union
Feb 03 17:24:30 gatesPi4 WeatherAPI[14465]: Running plumber API at http://192.168.1.151:9494
Feb 03 17:24:30 gatesPi4 WeatherAPI[14465]: Running swagger Docs at http://192.168.1.151:9494/__docs__/
Any ideas? I tried adding Users=pi
to the service file, to run as a user and not root, but no change in behavior. Any ideas?