-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #221 from MakeMonmouth/feature/220-SpaceAPI
Feature/220 space api
- Loading branch information
Showing
9 changed files
with
586 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,191 @@ | ||
# Space Directory | ||
|
||
The Space Directory functionality is provided via the [SpaceAPI](https://spaceapi.io) format. | ||
|
||
## Reading the data | ||
|
||
Any system can read the current information about the space by calling `https://<your_membermatters_installation>/api/spacedirectory/`. | ||
|
||
By default, this returns the following data: | ||
|
||
| Name | Description | Configuration Location | | ||
|------|-------------|------------------------| | ||
| space| The name of the space | Constance Config (Django Admin pages) | | ||
| logo | The uri of the space logo | Constance Config (Django Admin Pages)| | ||
| url | The URL of the membermatters installation | Django Base URL | | ||
| contact | Contact information, including email and various social media handles | Constance Config (Django Admin Pages)| | ||
| spacefed | Details of whether the Federated Hackspace Authentication service is running | Constance Config (Django Admin Pages)| | ||
| projects | A list of projects that the space is involved in | Constance Config (Django Admin Pages)| | ||
| issue_report_channels | What's the best way to report an issue? | Constance Config (Django Admin Pages)| | ||
| state | Is the state open or closed, and what message should we display? | Dynamic (Django Admin or API Endpoint) | | ||
| icon | An icon for each of "open" and "closed" | Constance Config (Django Admin Pages)| | ||
| api_compatibility | The version of the [SpaceAPI](https://spaceapi.io) that we are compatible with (can be multiple values) | Hard-coded based on Member Matters release version | | ||
| sensors | A dictionary of sensor data (and associated properties where relevant) as described in the [SpaceAPI JSON Schema documentation](https://spaceapi.io/docs/#schema-key-sensors) | Dynamic (Django Admin or API Endpoint) | | ||
| location | The physical location of the space including latitude and longitude | Constance Config (Django Admin Pages)| | ||
|
||
The data is returned as a JSON document. | ||
|
||
For tools that can help you interact with the data to display your current state on your homepage etc, visit the [SpaceAPI Tools](https://spaceapi.io/how-to-use/) page and have a play! | ||
|
||
## Updating the data | ||
|
||
For anything in table above that is marked as "dynamic", you can update that information via the API. | ||
|
||
Simply `POST` a JSON document to `https://<your_membermatters_installation>/api/spacedirectory/update` as an authenticated user, and the relevant fields will be updated. | ||
|
||
### Updating the status and the message | ||
|
||
Let's say you're opening the space and you want to ensure that everyone knows it's an "Open Night" (i.e. general public are welcome, not just members). | ||
|
||
You can do this with the following command: | ||
|
||
```bash | ||
curl -X POST -H 'Authorization: Api-Key <Your API KEY>' \ | ||
-d '{"is_open": true, "message": "Open Night TONIGHT! All Welcome between 1800hrs and 2300hrs"}' \ | ||
https://<your_membermatters_installation>/api/spacedirectory/update | ||
``` | ||
|
||
### Adding Sensor Data | ||
|
||
[Sensors](https://spaceapi.io/docs/#schema-key-sensors) are a really cool part of the SpaceAPI schema, as it allows you to publish all kinds of things from how many drinks are still in the fridge through to environment readings such as temperature, windspeed, and humidity. | ||
|
||
By default, MemberMatters exposes the total number of active members and how many have "signed in" to the space, however you can add your own sensors as long as they conform to the appropriate type. | ||
|
||
To update a sensor or property value, you just need to POST the appropriate JSON to `https://<your_membermatters_installation>/api/spacedirectory/update` as laid out below. | ||
|
||
**NOTE**: If a sensor or property is missing from the database then it will be created. If it exists but the value is not included or changed, it will not be updated. | ||
|
||
#### Sensors *without* properties | ||
|
||
Many of the sensors do not have any extra properties. Updating these is simple, as you just need to send a JSON array of dicts with the correct fields filled out: | ||
|
||
```json | ||
{ | ||
"sensors": [ | ||
{ | ||
"type": "temperature", | ||
"name": "test_sensor", | ||
"location": "default", | ||
"description": "This is a sensor", | ||
"unit": "°C", | ||
"value": 21.0 | ||
} | ||
] | ||
} | ||
``` | ||
|
||
Want to update more than one sensor at a time? No worries, just add to the array: | ||
|
||
```json | ||
{ | ||
"sensors": [ | ||
{ | ||
"type": "temperature", | ||
"name": "test_sensor", | ||
"location": "default", | ||
"description": "This is a sensor", | ||
"unit": "°C", | ||
"value": 21.0 | ||
}, | ||
{ | ||
"type": "humidity", | ||
"name": "test_sensor", | ||
"location": "default", | ||
"description": "This is a sensor", | ||
"unit": "%H", | ||
"value": 45.0 | ||
} | ||
] | ||
} | ||
``` | ||
|
||
#### Sensors *with* properties | ||
|
||
For those sensors that do have properties, only a few extra fields are required: | ||
|
||
```json | ||
{ | ||
"sensors": [ | ||
{ | ||
"type": "wind", | ||
"name": "wind_sensor_01", | ||
"location": "The Roof", | ||
"description": "A weather station", | ||
"properties": [ | ||
{ | ||
"name": "gust", | ||
"unit": "m/s", | ||
"speed": 5.0 | ||
} | ||
] | ||
} | ||
] | ||
} | ||
``` | ||
|
||
As with the sensors, additional properties can be created by adding more dictionaries to the properties array: | ||
|
||
|
||
```json | ||
{ | ||
"sensors": [ | ||
{ | ||
"type": "wind", | ||
"name": "wind_sensor_01", | ||
"location": "The Roof", | ||
"description": "A weather station", | ||
"properties": [ | ||
{ | ||
"name": "speed", | ||
"unit": "m/s", | ||
"speed": 5.0 | ||
}, | ||
{ | ||
"name": "gust", | ||
"unit": "m/s", | ||
"speed": 9.0 | ||
} | ||
] | ||
} | ||
] | ||
} | ||
``` | ||
|
||
### A full example | ||
|
||
The following JSON updates the space status to "Open", sets a message advising that there is a workshop running that evening, and sets the values for various sensors: | ||
|
||
```json | ||
|
||
{ "is_open": true, | ||
"message": "Soldering workshop tonight - 8pm to 10pm" | ||
"sensors": [ | ||
{ | ||
"type": "temperature", | ||
"name": "test_sensor", | ||
"location": "default", | ||
"description": "This is a sensor", | ||
"unit": "°C", | ||
"value": 21.0 | ||
}, | ||
{ | ||
"type": "wind", | ||
"name": "wind_sensor_01", | ||
"location": "The Roof", | ||
"description": "A weather station", | ||
"properties": [ | ||
{ | ||
"name": "speed", | ||
"unit": "m/s", | ||
"speed": 5.0 | ||
}, | ||
{ | ||
"name": "gust", | ||
"unit": "m/s", | ||
"speed": 9.0 | ||
} | ||
] | ||
} | ||
] | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
from django.contrib import admin | ||
from .models import SpaceAPI, SpaceAPISensor, SpaceAPISensorProperties | ||
|
||
|
||
@admin.register(SpaceAPI) | ||
class SpaceAPIAdmin(admin.ModelAdmin): | ||
pass | ||
|
||
|
||
@admin.register(SpaceAPISensor) | ||
class SpaceAPISensorAdmin(admin.ModelAdmin): | ||
pass | ||
|
||
|
||
@admin.register(SpaceAPISensorProperties) | ||
class SpaceAPISensorPropertiesAdmin(admin.ModelAdmin): | ||
pass |
98 changes: 98 additions & 0 deletions
98
memberportal/api_spacedirectory/migrations/0001_initial.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
# Generated by Django 3.2.21 on 2023-10-12 09:02 | ||
|
||
from django.db import migrations, models | ||
import django.db.models.deletion | ||
|
||
|
||
class Migration(migrations.Migration): | ||
initial = True | ||
|
||
dependencies = [] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name="SpaceAPI", | ||
fields=[ | ||
( | ||
"id", | ||
models.AutoField( | ||
auto_created=True, | ||
primary_key=True, | ||
serialize=False, | ||
verbose_name="ID", | ||
), | ||
), | ||
("space_is_open", models.BooleanField(default=False)), | ||
( | ||
"space_message", | ||
models.CharField(blank=True, max_length=255, null=True), | ||
), | ||
("status_last_change", models.DateTimeField(auto_now=True)), | ||
], | ||
), | ||
migrations.CreateModel( | ||
name="SpaceAPISensor", | ||
fields=[ | ||
( | ||
"id", | ||
models.AutoField( | ||
auto_created=True, | ||
primary_key=True, | ||
serialize=False, | ||
verbose_name="ID", | ||
), | ||
), | ||
( | ||
"sensor_type", | ||
models.CharField( | ||
choices=[ | ||
("temperature", "Temperature"), | ||
("barometer", "Barometer"), | ||
("radiation", "Radiation"), | ||
("humidity", "Humidity"), | ||
("beverage_supply", "Beverage Supply"), | ||
("power_consumption", "Power Consumption"), | ||
("wind", "Wind Data"), | ||
("network_connections", "Network Connections"), | ||
("account_balance", "Account Balance"), | ||
("network_traffic", "Network Traffic"), | ||
], | ||
max_length=100, | ||
), | ||
), | ||
("name", models.CharField(max_length=255)), | ||
("value", models.DecimalField(decimal_places=3, max_digits=10)), | ||
("unit", models.CharField(max_length=50)), | ||
("location", models.CharField(blank=True, max_length=255, null=True)), | ||
( | ||
"description", | ||
models.CharField(blank=True, max_length=255, null=True), | ||
), | ||
], | ||
), | ||
migrations.CreateModel( | ||
name="SpaceAPISensorProperties", | ||
fields=[ | ||
( | ||
"id", | ||
models.AutoField( | ||
auto_created=True, | ||
primary_key=True, | ||
serialize=False, | ||
verbose_name="ID", | ||
), | ||
), | ||
("name", models.CharField(max_length=100)), | ||
("value", models.DecimalField(decimal_places=3, max_digits=10)), | ||
("unit", models.CharField(max_length=100)), | ||
( | ||
"sensor_id", | ||
models.ForeignKey( | ||
on_delete=django.db.models.deletion.CASCADE, | ||
related_name="properties", | ||
to="api_spacedirectory.spaceapisensor", | ||
), | ||
), | ||
], | ||
), | ||
] |
24 changes: 24 additions & 0 deletions
24
memberportal/api_spacedirectory/migrations/0002_auto_20231012_1914.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# Generated by Django 3.2.21 on 2023-10-12 09:14 | ||
|
||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
dependencies = [ | ||
("api_spacedirectory", "0001_initial"), | ||
] | ||
|
||
operations = [ | ||
migrations.AlterField( | ||
model_name="spaceapisensor", | ||
name="unit", | ||
field=models.CharField(blank=True, max_length=50, null=True), | ||
), | ||
migrations.AlterField( | ||
model_name="spaceapisensor", | ||
name="value", | ||
field=models.DecimalField( | ||
blank=True, decimal_places=3, max_digits=10, null=True | ||
), | ||
), | ||
] |
Empty file.
Oops, something went wrong.