+Environmental friendly micro framing requires a lot of knowledge for the
+cultivation of a garden. As a consequence, a lot of newcomers and people
+switching from convention agriculture have trouble managing their garden. To
+resolve this problem, the **PlantMap Digital Logbook** was created, a digital
+representation of a garden, which monitors the plants and helps with
+instructions if problems like water deficiency or diseases are detected.
+
+![crops-view](docs/imgs/crops-tab.png)
## Table of Contents
-- [README](#readme)
- - [General](#general)
- - [Quick Start](#quick-start)
- - [Documentation](#documentation)
- - [Contributing](#contributing)
- - [License](#license)
+- [General](#general)
+- [Quick Start](#quick-start)
+- [Documentation](#documentation)
+- [Contributing](#contributing)
+- [License](#license)
## General
@@ -82,38 +89,28 @@ semantical environment representation
For running the application, we assume that you have a current version of
[Visual Studio Code](https://code.visualstudio.com/) and
-[Docker](https://www.docker.com/). Further, Visual Studio Code **needs** to have
+[Docker](https://www.docker.com/) installed. Further, Visual Studio Code **needs** to have
the **docker and the remote container extensions installed**. If you didn't
understand the requirements, please visit the [installation
guide](https://naturerobots.github.io/HSOS-SEP-PlantMap-2022/getting-started/installation/)
in the documentation for more detailed steps.
-To get started, clone the repository and open it in Visual Studio Code:
+If you just want to get the application running, clone the repository and run the docker compose command.
```sh
- git clone https://github.com/naturerobots/HSOS-SEP-PlantMap-2022.git
- cd HSOS-SEP-PlantMap-2022
- code .
+git clone https://github.com/naturerobots/HSOS-SEP-PlantMap-2022.git
+cd HSOS-SEP-PlantMap-2022
+docker compose -f .devcontainer/docker-compose.preview.yml up -d
```
-Next, we need to mount the current workspace into the projects docker container
-to use it as a preconfigured development environment. For that, you can press
-`F1` or `CTRL+SHIFT+P` and enter `Remote-Containers: Reopen Folder in Container`
-and confirm with `ENTER`. Visual Studio Code additionally shows a notification
-after opening the project in the bottom right corner with the same option. Now
-the [docker
-image](https://github.com/naturerobots/HSOS-SEP-PlantMap-2022/pkgs/container/plant-map-digital-logbook)
-of the project along with the images for the
- [PostgreSQL](https://www.postgresql.org/) database and the
- [RabbitMQ](https://www.rabbitmq.com/) message broker are downloaded.
- Additionally, the set-up of all required packages and extensions is handled.
-
-The default user for the container is:
-
-```shell
-user: docker
-password: docker
- ```
+Now the application should be available under
+[localhost:5000](http://localhost:5050), the REST API is runs on port 8000.
+
+To stop the application use :
+
+```sh
+docker compose -f .devcontainer/docker-compose.preview.yml stop
+```
## Documentation
@@ -129,8 +126,7 @@ learn and inspire. Any contributions are **greatly appreciated**.
This repository uses [pre-commit](https://pre-commit.com/) checks to verify the
code style before committing. Since the pre-commit checks are automatically
-installed in the development container, they are run before each commit you
-make. The checks can also be run manually with:
+installed, they are run before each commit. The checks can also be run manually with:
```bash
pre-commit run -a
diff --git a/docs/getting-started/improvements.md b/docs/getting-started/improvements.md
index 32d35ba..944db8f 100644
--- a/docs/getting-started/improvements.md
+++ b/docs/getting-started/improvements.md
@@ -1 +1,18 @@
# Improvements
+
+The following section contains suggestions for improving the application and may be extended much further.
+
+## Tiling of garden images to increase loading speed
+
+Administrators of companies or gardens have the ability to upload a (self-taken) picture of a garden using
+the web interface. The image can be displayed in the dashboard-, beds- or plants-view in the web interface,
+replacing the satellite image at the exact location of the garden, providing a much more detailed
+view of the beds and plants.
+
+High resolution images can have a large file size, this can lead to long loading times
+of the web interface, especially for users which have a slow internet connection.
+
+To solve this problem, a functionality could be implemented, which splits the uploaded image into many little
+square tiles. A single tile can be loaded much faster, because of the smaller file size. The tiles will be loaded
+incrementally, building the hole image. Users will have the advantage of seeing parts of the image earlier
+and having better visual feedback of the loading process.
diff --git a/docs/imgs/logo_small_white.svg b/docs/imgs/logo_small_white.svg
new file mode 100644
index 0000000..f0aa7d0
--- /dev/null
+++ b/docs/imgs/logo_small_white.svg
@@ -0,0 +1,9 @@
+
diff --git a/docs/reference/3d-view.md b/docs/reference/3d-view.md
new file mode 100644
index 0000000..f382e5c
--- /dev/null
+++ b/docs/reference/3d-view.md
@@ -0,0 +1,72 @@
+# 3D-View
+
+## Overview
+
+| Name | HTTP | URL | | |
+|---------------------------------------------------------------------|------|-----------------------------------------------------------------------------------|---|---|
+| [Get list of 3d meta plant information](#3d-meta-plant-information-list) | GET | `/companies//gardens//beds//3d-scene/` | | |
+
+## 3d meta plant information list
+
+Send a GET request to this endpoint to get the Plant information.
+The response contains two elements.
+Firstly an array called plants, which contains informations about every plant in the bed.
+Secondly an global element which describes center position of the bed.
+
+The plants array only contains plants for which the pointclouds are in the `django/storage/media/pointclouds/ply` folder.
+The pointcloud of a plant can be loaded by the url given in the plants array.
+
+for more information on how to access the pointclouds take a look at the [storage system](/reference/storage-system).
+
+**Request**: `/companies//gardens//beds//3d-scene/`
+**Response** `200 Ok`, `404 Not Found`, `400 Bad Request`
+
+Example response:
+
+```json
+{
+"plants": [
+ {
+ "geometryUUID": "a671dab73f9844b280ac4d36f0314ad5",
+ "measurementUUID": "8374c5058da64b73a7520955fc0c65fd",
+ "url": "http://localhost:8000/media/pointclouds/ply/e1ef73b1258b475a996d2b72924c27ac/a671dab73f9844b280ac4d36f0314ad5.ply",
+ "name": "crop 16",
+ "locationDescription": 1,
+ "type": "mangold",
+ "position": {
+ "x": "-2.0091417",
+ "y": "0.0038527877",
+ "z": "-0.817174"
+ },
+ "health": [
+ {
+ "type": "water",
+ "loglevel": 2,
+ "shortcut": "w"
+ },
+ {
+ "type": "nutrients",
+ "loglevel": 1,
+ "shortcut": "n"
+ },
+ {
+ "type": "diseases",
+ "loglevel": 3,
+ "shortcut": "d"
+ }
+ ],
+ "yield": 705.1650603082642,
+ "status": "vegetating",
+ "harvest": "4 Weeks",
+ "progress": "0.9351895742166416"
+ }
+ ],
+ "global": {
+ "position": {
+ "x": "-1.9149369",
+ "y": "-0.05081649",
+ "z": "-0.8281588"
+ }
+ }
+}
+```
diff --git a/docs/reference/external-apis.md b/docs/reference/external-apis.md
new file mode 100644
index 0000000..1e7ee75
--- /dev/null
+++ b/docs/reference/external-apis.md
@@ -0,0 +1,26 @@
+# External APIs
+
+## OpenWeatherMap
+
+The following [APIs](https://openweathermap.org/api) from [OpenWeatherMap](https://openweathermap.org/)
+were used for the `weather widget`.
+To use the APIs, an [OpenWeatherMap account](https://home.openweathermap.org/users/sign_up)
+and a [token](https://home.openweathermap.org/api_keys) must be created.
+The token must then be added as environment variable `VITE_TOKEN_OWM`.
+
+| API | Description | [Pricing](https://openweathermap.org/price) |
+|-----------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------|
+| [Current weather data](https://openweathermap.org/current) | Used to get the current temperature, weather and city name based on the coordinates of the garden. **The geocoder used in the API will soon be deprecated.** | 60 free calls/minute 1,000,000 free calls/month |
+| [One Call API 3.0](https://openweathermap.org/api/one-call-3) | Used to get the current day's temperature low and high, as well as the hourly forecast for temperature, rain probability, and wind speed and direction. | 1,000 free calls/day |
+| [Geocoding API](https://openweathermap.org/api/geocoding-api) | **Not used yet**, but the service has already been implemented for it, so it can be used when the `Current weater data API` geocoder API is deprecated. | 60 free calls/minute 1,000,000 free calls/month |
+
+## Mapbox
+
+The following [APIs](https://www.mapbox.com/product-apis) from [Mapbox](https://www.mapbox.com/)
+were used for the `garden map`.
+To use the APIs, an [Mapbox account](https://account.mapbox.com/auth/signup/) and a `token` must be created.
+The token must then be added as environment variable `VITE_TOKEN_MAPBOX`.
+
+| API | Description | [Pricing](https://www.mapbox.com/pricing) |
+|----------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------|----------------------------------|
+| [Static Tiles](https://docs.mapbox.com/api/maps/static-tiles/) | Used to add tiles to the map for the garden, so that the garden image can be better placed in the environment. | 200,000 free tile requests/month |
diff --git a/docs/reference/permissions.md b/docs/reference/permissions.md
index 14a1e93..34b9a4c 100644
--- a/docs/reference/permissions.md
+++ b/docs/reference/permissions.md
@@ -42,22 +42,22 @@ The following roles exist:
### Create company permission
Send a POST request to this endpoint to give a user permissions on the company specified in the URL.
-The request body needs to contain a `user_id` and a `permission` field as json.
+The request body needs to contain a `username` and a `permission` field as json.
Only admins of the corresponding company can access this endpoint.
-The following request with URL: ../companies/2/createPermission
-gives the user with id '42' admin permissions on the company with id '2':
+The following request with URL: `../companies/2/createPermission`
+gives the user with username `testuser` admin permissions on the company with id `2`:
```json
{
- "user_id": "42",
+ "username": "testuser",
"permission": "a"
}
```
-If a permission for this user and company already existed before, it will be deleted and a new one is created.
-Own permissions cannot be overwritten.
+If a permission for this user and company already exists, it will be overwritten. Own permissions cannot be overwritten,
+in order to prevent locking yourself out.
**Request**: `POST /companies/{company_id:int}/createPermission`
**Responses**:
@@ -70,17 +70,17 @@ Own permissions cannot be overwritten.
### Remove company permission
Send a POST request to this endpoint to remove the permissions of a user to the company specified in the URL.
-The request body needs to contain a `user_id` field as json.
+The request body needs to contain a `username` field as json.
Only admins of the corresponding company can access this endpoint.
Own permissions or those of the last admin cannot be removed.
-The following request with URL: ../companies/2/createPermission
-removes the permissions for the user with id '42' on the company with id '2':
+The following request with URL: `../companies/2/createPermission`
+removes the permissions for the user with username `testuser` on the company with id `2`:
```json
{
- "user_id": "42"
+ "username": "testuser"
}
```
diff --git a/docs/reference/storage-system.md b/docs/reference/storage-system.md
new file mode 100644
index 0000000..7ddf73b
--- /dev/null
+++ b/docs/reference/storage-system.md
@@ -0,0 +1,35 @@
+# Storage System
+
+## Basics
+
+To store files like the garden images, logs or plant pointclouds we use the storage folder.
+Images is a common folder, which allows to store files that are not accessible through an url.
+The logs folder uses the [django logging system](https://docs.djangoproject.com/en/4.1/topics/logging/).
+It is configured to contain two logs. `debug.log`, which shows all logs but can get kind of messy.
+For a cleaner logging experience we added the second log `info.log`, which shows everything except the logs defined as debug.
+As a third option for storage we added the media folder.
+everything inside this folder can be accessed through an url.
+For this we implemented the [django storage system](https://docs.djangoproject.com/en/4.1/ref/files/storage/).
+There is currently no system implemented to restrict the access to the data inside of the media folder.
+
+## Folder Structure
+
+Files inside the media folder can be accessed by `http://localhost:8000/media/`.
+An example GET request to the pointcloud of plant1 would look like this `http://localhost:8000/media/pointclouds/ply/05717c979b0d4bd790d31ce218cd58ee/06694a57e7cf4ee1acce970ab9d9d67a.ply`.
+
+```text
+storage
+├── images
+│ └── garden1.png
+├── logs
+│ ├── debug.log
+│ └── info.log
+└── media
+ └── pointclouds
+ └── ply
+ ├── 05717c979b0d4bd790d31ce218cd58ee
+ │ ├── 06694a57e7cf4ee1acce970ab9d9d67a.ply
+ │ ├── 0bf37a0851b7402d88674e153f58e6f8.ply
+ │ ├── 0d927fa6b3534f9580d1db73d483b254.ply
+ │ ├── ...
+```
diff --git a/docs/reference/terminology.md b/docs/reference/terminology.md
index 2c1fe78..2b2826a 100644
--- a/docs/reference/terminology.md
+++ b/docs/reference/terminology.md
@@ -4,8 +4,15 @@
![Definitions Bed - Garden - Company](../imgs/plant-map-companie-definitons-low.jpg)
-```text
-A: Bed
-B: Garden
-C: Company
-```
+### A: Bed
+
+A single row of soil, where crops/plants of the same variety are growing.
+
+### B: Garden
+
+Beds with different varieties of plants in a specified area together are forming a unit called garden.
+
+### C: Company
+
+All gardens and their corresponding beds belong to a company.
+The company has information about users/members supervising them.
diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css
index 24a9b18..ed839c5 100644
--- a/docs/stylesheets/extra.css
+++ b/docs/stylesheets/extra.css
@@ -1,5 +1,5 @@
[data-md-color-scheme="naturerobots"] {
- --md-primary-fg-color: #b6c1a7;
+ --md-primary-fg-color: #79b729;
--md-accent-fg-color: #9c9b9b;
--md-typeset-a-color: #26561d;
}
diff --git a/mkdocs.yml b/mkdocs.yml
index 22ff956..4fe1cb1 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -17,13 +17,16 @@ nav:
- Beds & Plants: "reference/bed-plant-endpoints.md"
- Company & Gardens: "reference/company-garden-endpoints.md"
- Permission System: "reference/permissions.md"
- - Env Variables: "reference/env-vars.md"
+ - 3D-View: "reference/3d-view.md"
+ - Storage System: "reference/storage-system.md"
- Architecture: "reference/architecture.md"
+ - External APIs: "reference/external-apis.md"
- Terminology: "reference/terminology.md"
+ - Env Variables: "reference/env-vars.md"
theme:
name: material
language: en
- logo: imgs/logo_small_color.svg
+ logo: imgs/logo_small_white.svg
favicon: imgs/logo_small_color.svg
palette:
- scheme: naturerobots
diff --git a/vue/src/components/sensor/SensorComp.vue b/vue/src/components/sensor/SensorComp.vue
index 84d88d4..cd854f4 100644
--- a/vue/src/components/sensor/SensorComp.vue
+++ b/vue/src/components/sensor/SensorComp.vue
@@ -73,7 +73,7 @@ function getRowBySensorId(sensorId: number): HTMLTableRowElement | undefined {
if (sensorId == table.value.rows[i].id) {
return document
.getElementsByClassName("q-table")[0]
- .getElementsByTagName("tr")[i + 1];
+ .getElementsByTagName("tr")[i + 2];
}
}
}
diff --git a/vue/src/components/three-scenes/CropScene.vue b/vue/src/components/three-scenes/CropScene.vue
index cbf0c1a..83c7cb2 100644
--- a/vue/src/components/three-scenes/CropScene.vue
+++ b/vue/src/components/three-scenes/CropScene.vue
@@ -243,7 +243,7 @@ onMounted(() => {
"/beds/" +
bedId.value +
"/3d-scene/";
- let payload = {};
+ //let payload = {};
let header = {
headers: {
Authorization: "Token " + storeToRefs(userStore()).getToken.value.token,
@@ -251,9 +251,9 @@ onMounted(() => {
};
axios
- .post(url, payload, header)
+ .get(url, header)
.then(function (response): void {
- //console.log("then", response);
+ console.log("then", response);
crop3dArray = response["data"]["plants"];
globalPosition = response["data"]["global"]["position"];
diff --git a/vue/src/services/bedApi.ts b/vue/src/services/bedApi.ts
index 2cf7a89..97deb9c 100644
--- a/vue/src/services/bedApi.ts
+++ b/vue/src/services/bedApi.ts
@@ -8,6 +8,8 @@ import type { Ref } from "vue";
const baseURL = "http://127.0.0.1:8000";
+let lastChunkFailed;
+
export async function loadBeds(): Promise {
const companyId: Ref = storeToRefs(
companyStore()
@@ -29,16 +31,27 @@ export async function loadBeds(): Promise {
},
}
).then(async (response) => {
- // response.body is a ReadableStream
const reader = response.body?.getReader();
const beds: Beds = {
bedList: [],
};
for await (const chunk of readChunks(reader)) {
if (chunk) {
- const json = JSON.parse(Utf8ArrayToStr(chunk));
- beds.bedList.push(json);
- bedStore().setBed(json);
+ let json;
+ try {
+ if (lastChunkFailed) {
+ lastChunkFailed += Utf8ArrayToStr(chunk);
+ json = JSON.parse(lastChunkFailed);
+ } else {
+ json = JSON.parse(Utf8ArrayToStr(chunk));
+ }
+ beds.bedList.push(json);
+ bedStore().setBed(json);
+ lastChunkFailed = null;
+ } catch (error) {
+ console.log(error);
+ lastChunkFailed = Utf8ArrayToStr(chunk);
+ }
}
}
return false;
diff --git a/vue/src/stores/bedStore.ts b/vue/src/stores/bedStore.ts
index b846fca..0f95f4f 100644
--- a/vue/src/stores/bedStore.ts
+++ b/vue/src/stores/bedStore.ts
@@ -41,6 +41,7 @@ export const bedStore = defineStore({
this.selectedBed = bedId;
},
setBed(bed: Bed) {
+ console.log(bed);
this.beds.bedList.push(bed);
},
},