This project provides an API for querying sensor data of our LoRaWAN based water temperature sensors. Check out https://gfrör.li for an application using the API.
The API uses token based authentication. A sample request looks like this:
curl 'http://localhost:3000/api/measurements' -H "Authorization: Bearer 0123456789ABCDEF" -v
All "index" and "show" resources are accessible with a public API key, while writing to the API is permitted only for consumers who provide a private API key.
The following endpoints are RESTful and allow full CRUD operations.
/api/sensors
/api/measurements
/api/sponsors
You can post a measurement to the api the following way (use the private api key of ApiConsumer):
curl -X POST 'http://localhost:3000/api/measurements' \
-H "Content-Type: application/json" \
-H "Authorization: Bearer 0123456789ABCDEF" \
-d '{"sensor_id": 1, "temperature": 20.7, "custom_attributes": {"foo": "bar"}}'
The following endpoints are optimized for mobile applications and return read-only aggregated data.
Sensors
Endpoint: /api/mobile_app/sensors
JSON array element fields:
Field | Type | Description |
---|---|---|
id | int | Sensor ID |
device_name | string | Sensor name |
caption | string | Caption describing the sensor |
created_at | uint | Unix timestamp (seconds) |
sponsor_id | uint? | Associated sponsor ID |
latitude | number | Latitude (WGS84) |
longitude | number | Longitude (WGS84) |
latest_temperature | number? | Latest temperature measurement |
latest_measurement_at | number? | Unix timestamp (seconds) |
Sensor Details
Endpoint: /api/mobile_app/sensors/<sensor-id>
JSON fields:
Field | Type | Description |
---|---|---|
id | int | Sensor ID |
device_name | string | Sensor name |
caption | string | Caption describing the sensor |
created_at | uint | Unix timestamp (seconds) |
sponsor_id | uint? | Associated sponsor ID |
latitude | number | Latitude (WGS84) |
longitude | number | Longitude (WGS84) |
latest_temperature | number? | Latest temperature measurement |
latest_measurement_at | number? | Unix timestamp (seconds) |
average_temperature | number? | Average temperature (all-time) |
minimum_temperature | number? | Lowest temperature (all-time) |
maximum_temperature | number? | Highest temperature (all-time) |
Sponsor
Endpoint: /api/mobile_app/sensors/<sensor-id>/sponsor
JSON fields:
Field | Type | Description |
---|---|---|
id | int | Sponsor ID |
name | string | Sponsor name |
description | string? | Sponsor description |
logo_url | string? | Logo URL (PNG) |
Sensor Daily Temperatures
Endpoint: /api/mobile_app/sensors/<sensor-id>/daily_temperatures
JSON array element fields:
Field | Type | Description |
---|---|---|
aggregation_date | string | ISO date (e.g. "2021-02-25") |
minimum_temperature | number | Lowest daily temperature |
maximum_temperature | number | Highest daily temperature |
average_temperature | number | Average daily temperature (arithmetic mean) |
Query parameters:
Param | Description | Default |
---|---|---|
from | Start date in ISO format (e.g. "2021-02-25") | 1989-04-07 |
to | End date in ISO format (e.g. "2021-02-25") | now |
limit | Max number of elements returned | 10 |
Sensor Hourly Temperatures
Endpoint: /api/mobile_app/sensors/<sensor-id>/hourly_temperatures
JSON array element fields:
Field | Type | Description |
---|---|---|
aggregation_date | string | ISO date (e.g. "2021-02-25") |
aggregation_hour | int | Hour of day (0-23) |
minimum_temperature | number | Lowest daily temperature |
maximum_temperature | number | Highest daily temperature |
average_temperature | number | Average daily temperature (arithmetic mean) |
Query parameters:
Param | Description | Default |
---|---|---|
from | Start date in ISO format (e.g. "2021-02-25") | 1989-04-07 |
to | End date in ISO format (e.g. "2021-02-25") | now |
limit | Max number of elements returned | 10 |
- Ruby 3.0
- Rails 6.1
bin/setup
bin/run
bin/check
To create an API consumer, run the following query on the database:
INSERT INTO api_consumers(public_api_key, private_api_key, caption, contact_email, created_at, updated_at)
VALUES('PUBLIC', 'PRIVATE', 'Test API Consumer', '[email protected]', NOW(), NOW());
You can run the entire setup with docker compose:
docker-compose build
docker-compose up -d
Now the server is running on http://localhost:3000/
.
If you're using docker-machine the server is running inside your virtual machine which has a different IP:
docker-machine ip default
To connect to the PostgreSQL database:
docker-compose exec db psql -U api watertemp_api
(Note: If you don't want to manually set up the entire dev environment, use the Docker instructions above!)
Install rbenv and ruby-build. On ArchLinux you can install them from the AUR:
To activate rbenv you need to add
eval "$(rbenv init -)"
To your shell init file (.bashrc
/.zshrc
).
git clone [email protected]:gfroerli/gfroerli-api.git
cd gfroerli-api
rbenv install
gem install bundler
pacman -S postgresql
sudo su - postgres -c "initdb --locale en_US.UTF-8 -D '/var/lib/postgres/data'"
createuser -U postgres --createdb $USERNAME
Copyright (C) 2016-2024 Gfrörli Developers
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.