planten class V1.1
3
.gitignore
vendored
@@ -1 +1,4 @@
|
||||
node_modules/
|
||||
__pycache__/
|
||||
venv/
|
||||
.vscode/
|
||||
|
||||
13
.hintrc
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"extends": [
|
||||
"development"
|
||||
],
|
||||
"hints": {
|
||||
"axe/text-alternatives": [
|
||||
"default",
|
||||
{
|
||||
"image-alt": "off"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
25
ReadMe.md
@@ -1,24 +1,33 @@
|
||||
# GoodGarden
|
||||
|
||||
Welkom bij ons project genaamd "GoodGarden". Wij hebben besloten om er een monolitische project van te maken. Alles is te vinden binnen deze repository.
|
||||
Welkom bij ons project genaamd "GoodGarden". Wij hebben besloten om er een semi-monolithic project van te maken. Alles is te vinden binnen deze repository, inclusief de "mqtt" publisher.
|
||||
|
||||
### Vereisten
|
||||
|
||||
* Python
|
||||
* Node.Js
|
||||
* XAMPP (of andere naar keuze)
|
||||
* MQTT Geinstalleerd en toegevoegd aan je PATH variable
|
||||
|
||||
### Installeren
|
||||
|
||||
Zorg dat je in de hoofdmap "GoodGarden" zit. Kijk in je path: "/GoodGarden". Als je in de correcte map zit moet je de volgende items installeren:
|
||||
Zorg dat je in de hoofdmap "GoodGarden" zit. Kijk in je path: "../GoodGarden". Als je in de correcte map zit moet je de volgende items installeren:
|
||||
|
||||
- npm install electron
|
||||
- npm install express
|
||||
- npm install body-parser
|
||||
- npm install python-shell
|
||||
npm install electron
|
||||
npm install express
|
||||
npm install body-parser
|
||||
npm install python-shell
|
||||
npm install --save-dev npm-run-all
|
||||
npm install wait-on --save-dev
|
||||
npm install concurrently --save-dev
|
||||
|
||||
|
||||
|
||||
|
||||
pip install mysql-connector-python
|
||||
pip install requests
|
||||
pip install flask-cors
|
||||
|
||||
- pip install mysql-connector-python
|
||||
- pip install requests
|
||||
|
||||
## Gebruik
|
||||
|
||||
|
||||
99
app.js
@@ -1,68 +1,109 @@
|
||||
const { app, BrowserWindow, ipcMain } = require('electron');
|
||||
const express = require('express');
|
||||
const bodyParser = require('body-parser');
|
||||
const { PythonShell } = require('python-shell');
|
||||
const path = require('path');
|
||||
const { app, BrowserWindow, ipcMain } = require("electron");
|
||||
const express = require("express");
|
||||
const bodyParser = require("body-parser");
|
||||
const { PythonShell } = require("python-shell");
|
||||
const path = require("path");
|
||||
|
||||
const urlElectron = path.join(__dirname, "src/index.html");
|
||||
|
||||
// Maak een Express-app
|
||||
const server = express();
|
||||
server.use(bodyParser.urlencoded({ extended: true }));
|
||||
|
||||
// Definieer een route voor form POST verzoeken
|
||||
server.post('/submit-form', (req, res) => {
|
||||
const { plant_naam, plantensoort } = req.body; // Verkrijg de plant_naam uit het formulier
|
||||
const plant_geteelt = req.body.plant_geteelt == 'true' ? 'true' : 'false'; // Zorgt dat de string "true" herkent wordt
|
||||
// Define a route for form POST requests
|
||||
server.post("/submit-form", (req, res) => {
|
||||
const { plant_naam, plantensoort } = req.body;
|
||||
const plant_geteelt = req.body.plant_geteelt == "true" ? "true" : "false";
|
||||
|
||||
let options = {
|
||||
mode: 'text',
|
||||
args: [plant_naam, plantensoort, plant_geteelt] // Zet hier een variable bij om de data toe te voegen aan de database
|
||||
mode: "text",
|
||||
args: [plant_naam, plantensoort, plant_geteelt],
|
||||
};
|
||||
|
||||
// Voer Python script uit met de plant_naam als argument
|
||||
PythonShell.run('./script/db_connect_form.py', options, (err, results) => {
|
||||
// Execute Python script with plant name as an argument
|
||||
PythonShell.run(
|
||||
"src/py/script/db_connect_form.py",
|
||||
options,
|
||||
(err, results) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
res.send('Er is een fout opgetreden');
|
||||
res.send("Er is een fout opgetreden");
|
||||
} else {
|
||||
console.log('Python script uitvoering resultaten:', results);
|
||||
res.send('Formulier succesvol verwerkt');
|
||||
console.log("Python script uitvoering resultaten:", results);
|
||||
res.send("Formulier succesvol verwerkt");
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
// Start de server voor verbinding met de database
|
||||
// Start the server
|
||||
const PORT = 3000;
|
||||
server.listen(PORT, () => {
|
||||
console.log(`Server luistert op port ${PORT}`);
|
||||
console.log(`Server is listening on port ${PORT}`);
|
||||
});
|
||||
|
||||
// Maak de Electron applicatie aan met bijbehorende waardes
|
||||
let mainWindow;
|
||||
|
||||
// Create the Electron application window
|
||||
function createWindow() {
|
||||
const mainWindow = new BrowserWindow({
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 1280,
|
||||
height: 800,
|
||||
frame: false,
|
||||
icon: path.join(__dirname, "src/py/static/images/logo.png"),
|
||||
webPreferences: {
|
||||
nodeIntegration: true,
|
||||
contextIsolation: false
|
||||
}
|
||||
contextIsolation: false,
|
||||
enableRemoteModule: true,
|
||||
webSecurity: true,
|
||||
},
|
||||
});
|
||||
|
||||
mainWindow.loadURL(urlElectron);
|
||||
mainWindow.loadFile(
|
||||
path.join(__dirname, "src", "py", "templates", "index.html")
|
||||
);
|
||||
|
||||
// IPC event listeners for running Python scripts and updating HTML data
|
||||
setupIpcMainListeners();
|
||||
}
|
||||
|
||||
// Start the Electron app
|
||||
app.whenReady().then(createWindow);
|
||||
|
||||
// Functionaliteit voor het openen en sluiten van de app
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
// Close the app when all windows are closed, except on macOS
|
||||
app.on("window-all-closed", () => {
|
||||
if (process.platform !== "darwin") {
|
||||
app.quit();
|
||||
}
|
||||
});
|
||||
|
||||
app.on('activate', () => {
|
||||
// Re-create a window in the app when the dock icon is clicked and there are no other windows open.
|
||||
app.on("activate", () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow();
|
||||
}
|
||||
});
|
||||
|
||||
function setupIpcMainListeners() {
|
||||
ipcMain.on("run-python-script", (event, args) => {
|
||||
let options = {
|
||||
mode: "text",
|
||||
args: args,
|
||||
};
|
||||
|
||||
// The actual script path and event replies should be tailored to your application's needs
|
||||
});
|
||||
|
||||
ipcMain.on("request-update-data", (event, args) => {
|
||||
const databaseData = {
|
||||
timestamp: "2022-01-01",
|
||||
gateway_receive_time: "2022-01-01",
|
||||
device: "Device1",
|
||||
value: 50,
|
||||
};
|
||||
event.reply("update-data-result", { databaseData });
|
||||
});
|
||||
|
||||
ipcMain.on("update-html-data", (event, data) => {
|
||||
mainWindow.webContents.send("update-html-data", data);
|
||||
});
|
||||
}
|
||||
|
||||
50
app.py
Normal file
@@ -0,0 +1,50 @@
|
||||
from flask import Flask, jsonify
|
||||
import mysql.connector
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
# Function to get data from the MySQL database
|
||||
def get_database_data():
|
||||
try:
|
||||
connection = mysql.connector.connect(
|
||||
host='localhost',
|
||||
user='root',
|
||||
password='',
|
||||
database='goodgarden'
|
||||
)
|
||||
cursor = connection.cursor()
|
||||
|
||||
# Query to retrieve the latest battery voltage data
|
||||
query = "SELECT id, timestamp, gateway_receive_time, device, value FROM battery_voltage_events ORDER BY timestamp DESC LIMIT 1"
|
||||
cursor.execute(query)
|
||||
battery_data = cursor.fetchone()
|
||||
|
||||
connection.close()
|
||||
|
||||
return battery_data
|
||||
except Exception as e:
|
||||
print("Error fetching data from database:", e)
|
||||
return None
|
||||
|
||||
@app.route('/', methods=['GET'])
|
||||
def get_data():
|
||||
# Get data from the database
|
||||
battery_data = get_database_data()
|
||||
|
||||
if battery_data is None:
|
||||
return jsonify({"error": "Failed to fetch data from database"})
|
||||
|
||||
# Convert the fetched data into a dictionary
|
||||
data_dict = {
|
||||
"id": battery_data[0],
|
||||
"timestamp": str(battery_data[1]), # Convert timestamp to string for JSON serialization
|
||||
"gateway_receive_time": str(battery_data[2]), # Convert timestamp to string for JSON serialization
|
||||
"device": battery_data[3],
|
||||
"value": battery_data[4]
|
||||
}
|
||||
|
||||
# Return the data as JSON
|
||||
return jsonify(data_dict)
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(host='127.0.0.1', port=5000)
|
||||
@@ -1,189 +1,7 @@
|
||||
# import requests #** TYPE IN TERMINAL: "pip install requests"
|
||||
# import time
|
||||
# import mysql.connector #** TYPE IN TERMINAL: "pip install mysql-connector-python"
|
||||
|
||||
# # Import python db_connect.py script
|
||||
# from db_connect import database_connect
|
||||
|
||||
# # Functie voor het aanmaken van gegevens in de database
|
||||
# def create_data(url, access_token, repeat_count=5):
|
||||
# for _ in range(repeat_count):
|
||||
# try:
|
||||
# headers = {
|
||||
# "Authorization": f"Token {access_token}"
|
||||
# }
|
||||
# response = requests.get(url, headers=headers)
|
||||
# response.raise_for_status()
|
||||
|
||||
# data = response.json()
|
||||
|
||||
# # print(f"Data from {url}:")
|
||||
# print(data)
|
||||
# insert_data(data)
|
||||
|
||||
# except requests.exceptions.RequestException as e:
|
||||
# print(f"Error fetching data from {url}: {e}")
|
||||
|
||||
# print("Waiting for the next create action...")
|
||||
# time.sleep(10)
|
||||
# # time.sleep(300)
|
||||
|
||||
# # Functie voor het invoegen van gegevens in de database
|
||||
# def insert_data(data):
|
||||
# mydb = database_connect()
|
||||
# if mydb.is_connected():
|
||||
# mycursor = mydb.cursor()
|
||||
|
||||
# insert_query = """
|
||||
# INSERT INTO goodgarden.battery_voltage_events (timestamp, gateway_receive_time, device, value)
|
||||
# VALUES (%s, %s, %s, %s)
|
||||
# """
|
||||
|
||||
# for record in data['results']: # Pas dit aan op basis van de werkelijke structuur van de JSON
|
||||
|
||||
# timestamp = record.get('timestamp', '')
|
||||
# gateway_receive_time = record.get('gateway_receive_time', '')
|
||||
# device = record.get('device', '')
|
||||
# value = record.get('value', '')
|
||||
|
||||
# print(f"Inserting data: timestamp={timestamp}, gateway_receive_time={gateway_receive_time}, device={device}, value={value}")
|
||||
|
||||
# # Voer de query uit
|
||||
# mycursor.execute(insert_query, (timestamp, gateway_receive_time, device, value))
|
||||
|
||||
# # Bevestig de wijzigingen
|
||||
# mydb.commit()
|
||||
|
||||
# # Sluit cursor en verbinding
|
||||
# mycursor.close()
|
||||
# mydb.close()
|
||||
|
||||
# # Functie voor het lezen van gegevens uit de database
|
||||
# def read_data(url, access_token, repeat_count=5):
|
||||
# for _ in range(repeat_count):
|
||||
# try:
|
||||
# headers = {
|
||||
# "Authorization": f"Token {access_token}"
|
||||
# }
|
||||
# response = requests.get(url, headers=headers)
|
||||
# response.raise_for_status()
|
||||
|
||||
# data = response.json()
|
||||
# print(f"Data from {url}:")
|
||||
# print(data)
|
||||
|
||||
# except requests.exceptions.RequestException as e:
|
||||
# print(f"Error fetching data from {url}: {e}")
|
||||
|
||||
# # Wacht een bepaalde tijd in secondes
|
||||
# print("Waiting for the next read action...")
|
||||
# time.sleep(300)
|
||||
|
||||
# # Functie voor het bijwerken van gegevens in de database
|
||||
# def update_data(record_id, new_value):
|
||||
# try:
|
||||
# mydb = database_connect()
|
||||
|
||||
# if mydb.is_connected():
|
||||
# mycursor = mydb.cursor()
|
||||
|
||||
# # Controleer of het record bestaat voordat je het bijwerkt
|
||||
# mycursor.execute("SELECT * FROM goodgarden.battery_voltage_events WHERE id = %s", (record_id,))
|
||||
# existing_record = mycursor.fetchone()
|
||||
|
||||
# if not existing_record:
|
||||
# print(f"Record with ID {record_id} not found. Update operation aborted.")
|
||||
# return
|
||||
|
||||
# # Hier moet je de juiste kolomnamen aanpassen op basis van de structuur van je database
|
||||
# update_query = """
|
||||
# UPDATE goodgarden.battery_voltage_events
|
||||
# SET value = %s
|
||||
# WHERE id = %s
|
||||
# """
|
||||
|
||||
# # Voer de query uit
|
||||
# print(f"Executing update query: {update_query}")
|
||||
# print(f"Updating record with ID {record_id} to new value: {new_value}")
|
||||
|
||||
# mycursor.execute(update_query, (new_value, record_id)) # Provide the tuple with values here
|
||||
|
||||
# # Bevestig de wijzigingen
|
||||
# mydb.commit()
|
||||
|
||||
# print(f"Update executed. Rowcount: {mycursor.rowcount}")
|
||||
|
||||
# except mysql.connector.Error as update_err:
|
||||
# print(f"Error updating data: {update_err}")
|
||||
# finally:
|
||||
# # Zorg ervoor dat je altijd de cursor en de databaseverbinding sluit
|
||||
# if 'mycursor' in locals() and mycursor is not None:
|
||||
# mycursor.close()
|
||||
# if 'mydb' in locals() and mydb.is_connected():
|
||||
# mydb.close()
|
||||
|
||||
|
||||
# # Functie voor het verwijderen van gegevens uit de database
|
||||
# def delete_data(record_id):
|
||||
# mydb = database_connect()
|
||||
# if mydb.is_connected():
|
||||
# mycursor = mydb.cursor()
|
||||
|
||||
# # Hier moet je de juiste kolomnamen aanpassen op basis van de structuur van je database
|
||||
# delete_query = """
|
||||
# DELETE FROM goodgarden.battery_voltage_events
|
||||
# WHERE id = %s
|
||||
# """
|
||||
|
||||
# # Voer de query uit
|
||||
# mycursor.execute(delete_query, (record_id,))
|
||||
|
||||
# # Bevestig de wijzigingen
|
||||
# mydb.commit()
|
||||
|
||||
# # Sluit cursor en verbinding
|
||||
# mycursor.close()
|
||||
# mydb.close()
|
||||
|
||||
# print(f"Data with ID {record_id} deleted.")
|
||||
|
||||
# if __name__ == "__main__":
|
||||
# url = "https://garden.inajar.nl/api/battery_voltage_events/?format=json"
|
||||
# access_token = "33bb3b42452306c58ecedc3c86cfae28ba22329c"
|
||||
|
||||
# repeat_count = 10
|
||||
|
||||
# operation_choice = input("Choose operation (C for Create, R for Read, U for Update, D for Delete): ").upper()
|
||||
|
||||
# # Maak gegevens aan
|
||||
# if operation_choice == "C":
|
||||
# create_data(url, access_token, repeat_count)
|
||||
|
||||
# # Lees gegevens
|
||||
# elif operation_choice == "R":
|
||||
# read_data(url, access_token, repeat_count)
|
||||
|
||||
# # Update gegevens
|
||||
# elif operation_choice == "U":
|
||||
# record_id = int(input("Enter record ID to update: "))
|
||||
# new_value = input("Enter new value: ")
|
||||
# update_data(record_id, new_value)
|
||||
|
||||
# # Verwijder gegevens
|
||||
# elif operation_choice == "D":
|
||||
# record_id = int(input("Enter record ID to delete: "))
|
||||
# delete_data(record_id)
|
||||
|
||||
# else:
|
||||
# print("Invalid operation choice. Please choose C, R, U, or D.")
|
||||
|
||||
import mysql.connector
|
||||
import requests
|
||||
from datetime import datetime, timezone, timedelta
|
||||
import time
|
||||
import os
|
||||
# import paho.mqtt.client as mqtt
|
||||
# from dotenv import load_dotenv
|
||||
|
||||
# Functie om verbinding te maken met de database
|
||||
def database_connect():
|
||||
@@ -199,12 +17,11 @@ def calculate_timestamp(gateway_receive_time):
|
||||
datetime_obj_utc = datetime.strptime(gateway_receive_time, "%Y-%m-%dT%H:%M:%SZ").replace(tzinfo=timezone.utc)
|
||||
|
||||
# Voeg het tijdsverschil van 1 uur toe voor de Nederlandse tijdzone (UTC+1)
|
||||
datetime_obj_nl = datetime_obj_utc + timedelta(hours=0)
|
||||
datetime_obj_nl = datetime_obj_utc + timedelta(hours=1)
|
||||
|
||||
# Formateer het datetime-object als een leesbare datumstring
|
||||
formatted_date = datetime_obj_nl.strftime("%Y-%m-%d %H:%M:%S")
|
||||
return formatted_date
|
||||
|
||||
# Functie voor het aanmaken van gegevens in de database
|
||||
def create_data(url, access_token, repeat_count=5):
|
||||
for _ in range(repeat_count):
|
||||
@@ -253,7 +70,6 @@ def create_data(url, access_token, repeat_count=5):
|
||||
print("Waiting for the next create action...\n")
|
||||
time.sleep(2)
|
||||
|
||||
# Functie voor het invoegen van gegevens in de database
|
||||
def insert_data(record):
|
||||
mydb = database_connect()
|
||||
if mydb.is_connected():
|
||||
@@ -264,26 +80,31 @@ def insert_data(record):
|
||||
INSERT INTO goodgarden.battery_voltage_events (timestamp, gateway_receive_time, device, value)
|
||||
VALUES (%s, %s, %s, %s)
|
||||
"""
|
||||
# Pas dit aan op basis van de werkelijke structuur van de JSON
|
||||
timestamp = calculate_timestamp(record.get('gateway_receive_time', ''))
|
||||
|
||||
try:
|
||||
# Voer de query uit zonder de timestamp te berekenen
|
||||
timestamp = record.get('timestamp', '')
|
||||
gateway_receive_time = record.get('gateway_receive_time', '')
|
||||
device = record.get('device', '')
|
||||
value = record.get('value', '')
|
||||
|
||||
print(f"Inserting data: timestamp={timestamp}, gateway_receive_time={gateway_receive_time}, device={device}, value={value}\n\n") # Print de ingevoerde gegevens
|
||||
print(f"Inserting data: timestamp={timestamp}, gateway_receive_time={gateway_receive_time}, device={device}, value={value}\n") # Print de ingevoerde gegevens
|
||||
|
||||
# Voer de query uit
|
||||
mycursor.execute(insert_query, (timestamp, gateway_receive_time, device, value))
|
||||
|
||||
# Bevestig de wijzigingen
|
||||
mydb.commit()
|
||||
|
||||
print("Data inserted into the database.")
|
||||
|
||||
except mysql.connector.Error as err:
|
||||
print(f"Error: {err}")
|
||||
|
||||
finally:
|
||||
# Sluit cursor en verbinding
|
||||
mycursor.close()
|
||||
mydb.close()
|
||||
|
||||
print("Data inserted into the database.")
|
||||
|
||||
# Functie voor het lezen van gegevens uit de database
|
||||
def read_data(url, access_token, repeat_count=5):
|
||||
for _ in range(repeat_count):
|
||||
316
goodgarden.sql
Normal file
@@ -0,0 +1,316 @@
|
||||
-- phpMyAdmin SQL Dump
|
||||
-- version 5.2.1
|
||||
-- https://www.phpmyadmin.net/
|
||||
--
|
||||
-- Host: 127.0.0.1
|
||||
-- Gegenereerd op: 20 mrt 2024 om 10:19
|
||||
-- Serverversie: 10.4.32-MariaDB
|
||||
-- PHP-versie: 8.2.12
|
||||
|
||||
DROP DATABASE IF EXISTS goodgarden;
|
||||
CREATE DATABASE goodgarden;
|
||||
|
||||
USE goodgarden;
|
||||
|
||||
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
|
||||
START TRANSACTION;
|
||||
SET time_zone = "+00:00";
|
||||
|
||||
|
||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
||||
/*!40101 SET NAMES utf8mb4 */;
|
||||
|
||||
--
|
||||
-- Database: `goodgarden`
|
||||
--
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabelstructuur voor tabel `battery_voltage_events`
|
||||
--
|
||||
|
||||
CREATE TABLE `battery_voltage_events` (
|
||||
`id` int(10) UNSIGNED NOT NULL,
|
||||
`timestamp` int(11) DEFAULT NULL,
|
||||
`gateway_receive_time` varchar(50) DEFAULT NULL,
|
||||
`device` int(11) DEFAULT NULL,
|
||||
`value` decimal(10,5) DEFAULT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
--
|
||||
-- Gegevens worden geëxporteerd voor tabel `battery_voltage_events`
|
||||
--
|
||||
|
||||
INSERT INTO `battery_voltage_events` (`id`, `timestamp`, `gateway_receive_time`, `device`, `value`) VALUES
|
||||
(2185, 1710839863, '2024-03-19T09:17:43Z', 256, 4.03663),
|
||||
(2186, 1710842346, '2024-03-19T09:59:06Z', 322, 4.08547);
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabelstructuur voor tabel `devices`
|
||||
--
|
||||
|
||||
CREATE TABLE `devices` (
|
||||
`id` int(10) UNSIGNED NOT NULL,
|
||||
`serial_number` varchar(255) DEFAULT NULL,
|
||||
`name` varchar(255) DEFAULT NULL,
|
||||
`label` varchar(255) DEFAULT NULL,
|
||||
`last_seen` int(11) DEFAULT NULL,
|
||||
`last_battery_voltage` float DEFAULT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabelstructuur voor tabel `fetch`
|
||||
--
|
||||
|
||||
CREATE TABLE `fetch` (
|
||||
`id` int(10) UNSIGNED NOT NULL,
|
||||
`timestamp` int(11) DEFAULT NULL,
|
||||
`gateway_receive_time` varchar(50) DEFAULT NULL,
|
||||
`device` int(11) DEFAULT NULL,
|
||||
`value` decimal(10,5) DEFAULT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabelstructuur voor tabel `par_events`
|
||||
--
|
||||
|
||||
CREATE TABLE `par_events` (
|
||||
`id` int(10) UNSIGNED NOT NULL,
|
||||
`timestamp` int(11) DEFAULT NULL,
|
||||
`gateway_receive_time` varchar(50) DEFAULT NULL,
|
||||
`device` int(11) DEFAULT NULL,
|
||||
`value` decimal(10,5) DEFAULT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabelstructuur voor tabel `planten`
|
||||
--
|
||||
|
||||
CREATE TABLE `planten` (
|
||||
`id` int(20) UNSIGNED NOT NULL,
|
||||
`plant_naam` varchar(255) DEFAULT NULL,
|
||||
`plantensoort` varchar(255) DEFAULT NULL,
|
||||
`plant_geteelt` tinyint(1) DEFAULT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
--
|
||||
-- Gegevens worden geëxporteerd voor tabel `planten`
|
||||
--
|
||||
|
||||
INSERT INTO `planten` (`id`, `plant_naam`, `plantensoort`, `plant_geteelt`) VALUES
|
||||
(47, 'Tomaten', 'Groente', 1),
|
||||
(49, 'Komkommer', 'Groente', 1),
|
||||
(50, 'Appel', 'Fruit', 1),
|
||||
(51, 'Sla', 'Groente', 1),
|
||||
(52, 'Wietplant', 'Onkruid', 0);
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabelstructuur voor tabel `relative_humidity_events`
|
||||
--
|
||||
|
||||
CREATE TABLE `relative_humidity_events` (
|
||||
`id` int(10) UNSIGNED NOT NULL,
|
||||
`timestamp` int(11) DEFAULT NULL,
|
||||
`gateway_receive_time` varchar(50) DEFAULT NULL,
|
||||
`device` int(11) DEFAULT NULL,
|
||||
`value` decimal(10,5) DEFAULT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabelstructuur voor tabel `soil_electric_conductivity_events`
|
||||
--
|
||||
|
||||
CREATE TABLE `soil_electric_conductivity_events` (
|
||||
`id` int(10) UNSIGNED NOT NULL,
|
||||
`timestamp` int(11) DEFAULT NULL,
|
||||
`gateway_receive_time` varchar(50) DEFAULT NULL,
|
||||
`device` int(11) DEFAULT NULL,
|
||||
`value` decimal(10,5) DEFAULT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabelstructuur voor tabel `soil_relative_permittivity_events`
|
||||
--
|
||||
|
||||
CREATE TABLE `soil_relative_permittivity_events` (
|
||||
`id` int(10) UNSIGNED NOT NULL,
|
||||
`timestamp` int(11) DEFAULT NULL,
|
||||
`gateway_receive_time` varchar(50) DEFAULT NULL,
|
||||
`device` int(11) DEFAULT NULL,
|
||||
`value` decimal(10,5) DEFAULT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabelstructuur voor tabel `soil_temperature_events`
|
||||
--
|
||||
|
||||
CREATE TABLE `soil_temperature_events` (
|
||||
`id` int(10) NOT NULL,
|
||||
`timestamp` int(11) DEFAULT NULL,
|
||||
`gateway_receive_time` varchar(50) DEFAULT NULL,
|
||||
`device` int(11) DEFAULT NULL,
|
||||
`value` decimal(10,5) DEFAULT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
--
|
||||
-- Indexen voor geëxporteerde tabellen
|
||||
--
|
||||
|
||||
--
|
||||
-- Indexen voor tabel `battery_voltage_events`
|
||||
--
|
||||
ALTER TABLE `battery_voltage_events`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD UNIQUE KEY `timestamp` (`timestamp`),
|
||||
ADD UNIQUE KEY `gateway_receive_time` (`gateway_receive_time`);
|
||||
|
||||
--
|
||||
-- Indexen voor tabel `devices`
|
||||
--
|
||||
ALTER TABLE `devices`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD UNIQUE KEY `last_seen` (`last_seen`),
|
||||
ADD UNIQUE KEY `last_battery_voltage` (`last_battery_voltage`);
|
||||
|
||||
--
|
||||
-- Indexen voor tabel `fetch`
|
||||
--
|
||||
ALTER TABLE `fetch`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD UNIQUE KEY `timestamp` (`timestamp`),
|
||||
ADD UNIQUE KEY `gateway_receive_time` (`gateway_receive_time`),
|
||||
ADD UNIQUE KEY `value` (`value`);
|
||||
|
||||
--
|
||||
-- Indexen voor tabel `par_events`
|
||||
--
|
||||
ALTER TABLE `par_events`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD UNIQUE KEY `timestamp` (`timestamp`),
|
||||
ADD UNIQUE KEY `gateway_receive_time` (`gateway_receive_time`),
|
||||
ADD UNIQUE KEY `value` (`value`);
|
||||
|
||||
--
|
||||
-- Indexen voor tabel `planten`
|
||||
--
|
||||
ALTER TABLE `planten`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD UNIQUE KEY `plant_naam` (`plant_naam`);
|
||||
|
||||
--
|
||||
-- Indexen voor tabel `relative_humidity_events`
|
||||
--
|
||||
ALTER TABLE `relative_humidity_events`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD UNIQUE KEY `timestamp` (`timestamp`),
|
||||
ADD UNIQUE KEY `gateway_receive_time` (`gateway_receive_time`),
|
||||
ADD UNIQUE KEY `value` (`value`);
|
||||
|
||||
--
|
||||
-- Indexen voor tabel `soil_electric_conductivity_events`
|
||||
--
|
||||
ALTER TABLE `soil_electric_conductivity_events`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD UNIQUE KEY `timestamp` (`timestamp`),
|
||||
ADD UNIQUE KEY `gateway_receive_time` (`gateway_receive_time`),
|
||||
ADD UNIQUE KEY `value` (`value`);
|
||||
|
||||
--
|
||||
-- Indexen voor tabel `soil_relative_permittivity_events`
|
||||
--
|
||||
ALTER TABLE `soil_relative_permittivity_events`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD UNIQUE KEY `timestamp` (`timestamp`),
|
||||
ADD UNIQUE KEY `gateway_receive_time` (`gateway_receive_time`),
|
||||
ADD UNIQUE KEY `value` (`value`);
|
||||
|
||||
--
|
||||
-- Indexen voor tabel `soil_temperature_events`
|
||||
--
|
||||
ALTER TABLE `soil_temperature_events`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD UNIQUE KEY `timestamp` (`timestamp`),
|
||||
ADD UNIQUE KEY `gateway_receive_time` (`gateway_receive_time`),
|
||||
ADD UNIQUE KEY `value` (`value`);
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT voor geëxporteerde tabellen
|
||||
--
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT voor een tabel `battery_voltage_events`
|
||||
--
|
||||
ALTER TABLE `battery_voltage_events`
|
||||
MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2189;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT voor een tabel `devices`
|
||||
--
|
||||
ALTER TABLE `devices`
|
||||
MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=15;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT voor een tabel `fetch`
|
||||
--
|
||||
ALTER TABLE `fetch`
|
||||
MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=100;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT voor een tabel `par_events`
|
||||
--
|
||||
ALTER TABLE `par_events`
|
||||
MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=7;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT voor een tabel `planten`
|
||||
--
|
||||
ALTER TABLE `planten`
|
||||
MODIFY `id` int(20) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=53;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT voor een tabel `relative_humidity_events`
|
||||
--
|
||||
ALTER TABLE `relative_humidity_events`
|
||||
MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=9;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT voor een tabel `soil_electric_conductivity_events`
|
||||
--
|
||||
ALTER TABLE `soil_electric_conductivity_events`
|
||||
MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=5;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT voor een tabel `soil_relative_permittivity_events`
|
||||
--
|
||||
ALTER TABLE `soil_relative_permittivity_events`
|
||||
MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT voor een tabel `soil_temperature_events`
|
||||
--
|
||||
ALTER TABLE `soil_temperature_events`
|
||||
MODIFY `id` int(10) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=8;
|
||||
COMMIT;
|
||||
|
||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
||||
BIN
mqtt/__pycache__/__init__.cpython-311.pyc
Normal file
BIN
mqtt/__pycache__/db_connect.cpython-311.pyc
Normal file
BIN
mqtt/__pycache__/mqtt_client.cpython-311.pyc
Normal file
16
mqtt/db_connect.py
Normal file
@@ -0,0 +1,16 @@
|
||||
import mysql.connector
|
||||
from mysql.connector import Error
|
||||
|
||||
def database_connect():
|
||||
try:
|
||||
connection = mysql.connector.connect(
|
||||
host="localhost",
|
||||
user="root",
|
||||
password="",
|
||||
database="goodgarden"
|
||||
)
|
||||
if connection.is_connected():
|
||||
return connection
|
||||
except Error as e:
|
||||
print(f"Connection NIET gelukt! ${e}")
|
||||
return None
|
||||
15
mqtt/mqtt_client.py
Normal file
@@ -0,0 +1,15 @@
|
||||
import paho.mqtt.client as mqtt
|
||||
|
||||
def create_client(client_id, on_connect, on_message, broker="localhost", port=1883):
|
||||
client = mqtt.Client(client_id)
|
||||
client.on_connect = on_connect
|
||||
client.on_message = on_message
|
||||
|
||||
client.connect(broker, port, 60)
|
||||
return client
|
||||
|
||||
def start_loop(client):
|
||||
try:
|
||||
client.loop_forever()
|
||||
except KeyboardInterrupt:
|
||||
print("Disconnecting from broker")
|
||||
60
mqtt/publisher.py
Normal file
@@ -0,0 +1,60 @@
|
||||
import requests
|
||||
import time
|
||||
import json
|
||||
|
||||
from mqtt_client import create_client, start_loop
|
||||
|
||||
publish_interval = 30 # Secondes om een aanvraag te doen - MOET ~300 ZIJN!!!!!!!!!
|
||||
|
||||
api_endpoints = [
|
||||
{"url": "https://garden.inajar.nl/api/devices/", "topic": "goodgarden/devices"},
|
||||
{"url": "https://garden.inajar.nl/api/relative_humidity_events/", "topic": "goodgarden/relative_humidity"},
|
||||
{"url": "https://garden.inajar.nl/api/battery_voltage_events/", "topic": "goodgarden/battery_voltage"},
|
||||
{"url": "https://garden.inajar.nl/api/soil_electric_conductivity_events/", "topic": "goodgarden/soil_electric_conductivity"},
|
||||
{"url": "https://garden.inajar.nl/api/soil_relative_permittivity_events/", "topic": "goodgarden/soil_relative_permittivity"},
|
||||
{"url": "https://garden.inajar.nl/api/soil_temperature_events/", "topic": "goodgarden/soil_temperature"},
|
||||
{"url": "https://garden.inajar.nl/api/par_events/", "topic": "goodgarden/par_events"}
|
||||
]
|
||||
|
||||
def on_connect(client, userdata, flags, rc):
|
||||
print("Connected with result code "+str(rc))
|
||||
|
||||
def on_message(client, userdata, msg):
|
||||
print(f"Message: {msg.topic} {str(msg.payload)}")
|
||||
|
||||
client = create_client("publisher1", on_connect, on_message) # Gebruik een unieke client ID
|
||||
|
||||
def publish_to_mqtt(topic, data):
|
||||
|
||||
json_data = json.dumps(data) # Serialiseer de data naar een JSON-string
|
||||
client.publish(topic, json_data)
|
||||
print(f"\033[92mData published to MQTT topic {topic}.\033[0m")
|
||||
|
||||
|
||||
def fetch_and_publish_data():
|
||||
|
||||
for endpoint in api_endpoints:
|
||||
url = endpoint["url"]
|
||||
mqtt_topic = endpoint["topic"]
|
||||
access_token = "33bb3b42452306c58ecedc3c86cfae28ba22329c"
|
||||
|
||||
try:
|
||||
headers = {"Authorization": f"Token {access_token}"}
|
||||
response = requests.get(url, headers=headers)
|
||||
response.raise_for_status() # Zorgt ervoor dat HTTPError wordt opgeworpen voor slechte responses
|
||||
data = response.json()
|
||||
print(f"Data from {url}: {data}")
|
||||
publish_to_mqtt(mqtt_topic, data)
|
||||
# load_data(data) # Zorg ervoor dat deze functie elders gedefinieerd is
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"Error fetching data from {url}: {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
client.loop_start() # Start de niet-blokkerende loop
|
||||
while True:
|
||||
fetch_and_publish_data()
|
||||
print(f"\033[91mWachten, wachten en nog eens wachten... {publish_interval} secondes!\033[0m\n")
|
||||
|
||||
|
||||
time.sleep(publish_interval)
|
||||
client.loop_stop()
|
||||
4155
package-lock.json
generated
11
package.json
@@ -3,15 +3,20 @@
|
||||
"description": "",
|
||||
"main": "app.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"start": "electron app.js"
|
||||
"start": "npm-run-all --parallel start-flask start-electron",
|
||||
"start-electron": "wait-on http://localhost:5000 && electron app.js",
|
||||
"start-flask": "python app.py"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"electron": "^23.3.13"
|
||||
"concurrently": "^8.2.2",
|
||||
"electron": "^23.3.13",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"wait-on": "^7.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^1.6.7",
|
||||
"body-parser": "^1.20.2",
|
||||
"elctron": "^0.0.1-security",
|
||||
"express": "^4.18.3",
|
||||
|
||||
32
plants.json
Normal file
@@ -0,0 +1,32 @@
|
||||
[
|
||||
{
|
||||
"id": 47,
|
||||
"plant_naam": "Tomaten",
|
||||
"plantensoort": "Groente",
|
||||
"plant_geteelt": 1
|
||||
},
|
||||
{
|
||||
"id": 49,
|
||||
"plant_naam": "Komkommer",
|
||||
"plantensoort": "Groente",
|
||||
"plant_geteelt": 1
|
||||
},
|
||||
{
|
||||
"id": 50,
|
||||
"plant_naam": "Appel",
|
||||
"plantensoort": "Fruit",
|
||||
"plant_geteelt": 1
|
||||
},
|
||||
{
|
||||
"id": 51,
|
||||
"plant_naam": "Sla",
|
||||
"plantensoort": "Groente",
|
||||
"plant_geteelt": 1
|
||||
},
|
||||
{
|
||||
"id": 52,
|
||||
"plant_naam": "Wietplant",
|
||||
"plantensoort": "Onkruid",
|
||||
"plant_geteelt": 0
|
||||
}
|
||||
]
|
||||
@@ -1,71 +0,0 @@
|
||||
import requests
|
||||
import time
|
||||
|
||||
from db_connect import database_connect
|
||||
|
||||
def fetch_and_display_all(url, access_token, repeat_count=5):
|
||||
for _ in range(repeat_count):
|
||||
try:
|
||||
headers = {
|
||||
"Authorization": f"Token {access_token}"
|
||||
}
|
||||
response = requests.get(url, headers=headers)
|
||||
response.raise_for_status()
|
||||
|
||||
data = response.json()
|
||||
print(f"Data from {url}:")
|
||||
print(data)
|
||||
load_data(data)
|
||||
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"Error fetching data from {url}: {e}")
|
||||
|
||||
print("Waiting for the next retrieval action...")
|
||||
|
||||
# time.sleep(300) # Time here is in seconds.
|
||||
|
||||
time.sleep(1) # Time here is in seconds.
|
||||
|
||||
def load_data(data):
|
||||
mydb = database_connect()
|
||||
if mydb.is_connected():
|
||||
mycursor = mydb.cursor()
|
||||
|
||||
# Here you need to adjust the correct column names and data formats based on the API response
|
||||
insert_query = """
|
||||
INSERT INTO goodgarden.devices (serial_number, name, label, last_seen, last_battery_voltage)
|
||||
VALUES (%s, %s, %s, %s, %s )
|
||||
"""
|
||||
for record in data['results']:
|
||||
serial_number = record.get('serial_number', '')
|
||||
name = record.get('name', '')
|
||||
label = record.get('label', '')
|
||||
last_seen = record.get('last_seen', '')
|
||||
last_battery_voltage = record.get('last_battery_voltage', '')
|
||||
|
||||
print(f"Inserting data: serial_number={serial_number}, name={name}, label={label}, last_seen={last_seen}, last_battery_voltage={last_battery_voltage}")
|
||||
|
||||
# Execute the query
|
||||
mycursor.execute(insert_query, (serial_number, name, label, last_seen, last_battery_voltage))
|
||||
|
||||
# Commit the changes
|
||||
mydb.commit()
|
||||
|
||||
# Close cursor and connection
|
||||
mycursor.close()
|
||||
mydb.close()
|
||||
|
||||
print("Data inserted into the database.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
url = "https://garden.inajar.nl/api/devices/?format=json"
|
||||
access_token = "33bb3b42452306c58ecedc3c86cfae28ba22329c" # Replace this with your actual access token
|
||||
|
||||
|
||||
# access_token = "33bb3b42452306c58ecedc3c86cfae28ba22329c"
|
||||
|
||||
# You can change the repeat_count to control how many times you want to repeat the process
|
||||
repeat_count = 10
|
||||
|
||||
|
||||
fetch_and_display_all(url, access_token, repeat_count)
|
||||
@@ -1,73 +0,0 @@
|
||||
import requests
|
||||
import time
|
||||
|
||||
from db_connect import database_connect
|
||||
|
||||
# Establish a database connection
|
||||
connection = database_connect()
|
||||
|
||||
def fetch_and_display_all(urls, access_token):
|
||||
for url in urls:
|
||||
try:
|
||||
headers = {
|
||||
"Authorization": f"Token {access_token}"
|
||||
}
|
||||
response = requests.get(url, headers=headers)
|
||||
response.raise_for_status()
|
||||
|
||||
data = response.json()
|
||||
print(f"Data from {url}:")
|
||||
print(data)
|
||||
load_data(data)
|
||||
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"Error fetching data from {url}: {e}")
|
||||
|
||||
# Wait for a certain time (e.g., 60 seconds) before making the next call
|
||||
print("Waiting for the next retrieval action...")
|
||||
time.sleep(10) # Time here is in seconds.
|
||||
|
||||
def load_data(data):
|
||||
mydb = database_connect()
|
||||
if mydb.is_connected():
|
||||
mycursor = mydb.cursor()
|
||||
|
||||
# Here you need to adjust the correct column names and data formats based on the API response
|
||||
insert_query = """
|
||||
INSERT INTO goodgarden.fetch (timestamp, gateway_receive_time, device, value)
|
||||
VALUES (%s, %s, %s, %s)
|
||||
"""
|
||||
for record in data['results']: # Adjust this based on the actual structure of the JSON
|
||||
timestamp = record.get('timestamp', '')
|
||||
gateway_receive_time = record.get('gateway_receive_time', '')
|
||||
device = record.get('device', '')
|
||||
value = record.get('value', '')
|
||||
|
||||
print(f"Inserting data: timestamp={timestamp}, gateway_receive_time={gateway_receive_time}, device={device}, value={value}") # Print the data being inserted
|
||||
|
||||
# Execute the query
|
||||
mycursor.execute(insert_query, (timestamp, gateway_receive_time, device, value))
|
||||
|
||||
# Commit the changes
|
||||
mydb.commit()
|
||||
|
||||
# Close cursor and connection
|
||||
mycursor.close()
|
||||
mydb.close()
|
||||
|
||||
print("Data inserted into the database.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
urls = [
|
||||
"https://garden.inajar.nl/api/battery_voltage_events/?format=json",
|
||||
"https://garden.inajar.nl/api/devices/?format=json",
|
||||
"https://garden.inajar.nl/api/par_events/?format=json",
|
||||
"https://garden.inajar.nl/api/relative_humidity_events/?format=json",
|
||||
"https://garden.inajar.nl/api/soil_electric_conductivity_events/?format=json",
|
||||
"https://garden.inajar.nl/api/soil_relative_permittivity_events/?format=json",
|
||||
"https://garden.inajar.nl/api/soil_temperature_events/?format=json"
|
||||
]
|
||||
|
||||
access_token = "33bb3b42452306c58ecedc3c86cfae28ba22329c" # Vervang dit met jouw echte toegangstoken
|
||||
|
||||
fetch_and_display_all(urls, access_token)
|
||||
@@ -1,57 +0,0 @@
|
||||
import requests
|
||||
import time
|
||||
|
||||
from db_connect import database_connect
|
||||
|
||||
def fetch_battery_voltage_events():
|
||||
url = "https://garden.inajar.nl/api/battery_voltage_events/?format=json"
|
||||
headers = {
|
||||
"Authorization": "Token 33bb3b42452306c58ecedc3c86cfae28ba22329c"
|
||||
}
|
||||
|
||||
while True:
|
||||
try:
|
||||
response = requests.get(url, headers=headers)
|
||||
response.raise_for_status()
|
||||
|
||||
data = response.json()
|
||||
load_data(data)
|
||||
|
||||
print("Wachten voor de volgende ophaalactie...")
|
||||
time.sleep(300) # De tijd hier is in seconden.
|
||||
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"Error fetching data: {e}")
|
||||
# Wacht ook hier bij een fout, om niet in een snelle foutloop te komen
|
||||
time.sleep(300)
|
||||
|
||||
def load_data(data):
|
||||
mydb = database_connect()
|
||||
if mydb.is_connected():
|
||||
mycursor = mydb.cursor()
|
||||
|
||||
# Hier moet je de juiste kolomnamen en dataformaten aanpassen op basis van de API-respons
|
||||
insert_query = """
|
||||
INSERT INTO goodgarden.battery_voltage_events (timestamp, gateway_receive_time, device, value)
|
||||
VALUES (%s, %s, %s, %s)
|
||||
"""
|
||||
for record in data['results']:
|
||||
timestamp = record['timestamp']
|
||||
gateway_receive_time = record['gateway_receive_time']
|
||||
device = record['device']
|
||||
value = record['value']
|
||||
|
||||
# print(f"Inserting data: timestamp={timestamp}, gateway_receive_time={gateway_receive_time}, device={device}, value={value}")
|
||||
mycursor.execute(insert_query, (timestamp, gateway_receive_time, device, value))
|
||||
|
||||
# Commit de wijzigingen
|
||||
mydb.commit()
|
||||
|
||||
# Sluit cursor en verbinding
|
||||
mycursor.close()
|
||||
mydb.close()
|
||||
|
||||
print("Data ingevoegd in de database.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
fetch_battery_voltage_events()
|
||||
@@ -1,64 +0,0 @@
|
||||
import requests
|
||||
import time
|
||||
|
||||
from db_connect import database_connect
|
||||
|
||||
def fetch_and_display_all(url, access_token, repeat_count=5):
|
||||
for _ in range(repeat_count):
|
||||
try:
|
||||
headers = {
|
||||
"Authorization": f"Token {access_token}"
|
||||
}
|
||||
response = requests.get(url, headers=headers)
|
||||
response.raise_for_status()
|
||||
|
||||
data = response.json()
|
||||
print(f"Data from {url}:")
|
||||
print(data)
|
||||
load_data(data)
|
||||
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"Error fetching data from {url}: {e}")
|
||||
|
||||
print("Waiting for the next retrieval action...")
|
||||
|
||||
time.sleep(1) # Time here is in seconds.
|
||||
|
||||
|
||||
def load_data(data):
|
||||
mydb = database_connect()
|
||||
if mydb.is_connected():
|
||||
mycursor = mydb.cursor()
|
||||
|
||||
# Here you need to adjust the correct column names and data formats based on the API response
|
||||
insert_query = """
|
||||
INSERT INTO goodgarden.par_events (timestamp, gateway_receive_time, device, value)
|
||||
VALUES (%s, %s, %s, %s)
|
||||
"""
|
||||
for record in data['results']:
|
||||
timestamp = record.get('timestamp', '')
|
||||
gateway_receive_time = record.get('gateway_receive_time', '')
|
||||
device = record.get('device', '')
|
||||
value = record.get('value', '')
|
||||
|
||||
print(f"Inserting data: timestamp={timestamp}, gateway_receive_time={gateway_receive_time}, device={device}, value={value}")
|
||||
|
||||
# Execute the query
|
||||
mycursor.execute(insert_query, (timestamp, gateway_receive_time, device, value))
|
||||
|
||||
# Commit the changes
|
||||
mydb.commit()
|
||||
|
||||
# Close cursor and connection
|
||||
mycursor.close()
|
||||
mydb.close()
|
||||
|
||||
print("Data inserted into the database.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
url = "https://garden.inajar.nl/api/par_events/?format=json"
|
||||
access_token = "33bb3b42452306c58ecedc3c86cfae28ba22329c"
|
||||
# You can change the repeat_count to control how many times you want to repeat the process
|
||||
repeat_count = 10
|
||||
|
||||
fetch_and_display_all(url, access_token, repeat_count)
|
||||
@@ -1,64 +0,0 @@
|
||||
import requests
|
||||
import time
|
||||
|
||||
from db_connect import database_connect
|
||||
|
||||
def fetch_and_display_all(url, access_token, repeat_count=5):
|
||||
for _ in range(repeat_count):
|
||||
try:
|
||||
headers = {
|
||||
"Authorization": f"Token {access_token}"
|
||||
}
|
||||
response = requests.get(url, headers=headers)
|
||||
response.raise_for_status()
|
||||
|
||||
data = response.json()
|
||||
print(f"Data from {url}:")
|
||||
print(data)
|
||||
load_data(data)
|
||||
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"Error fetching data from {url}: {e}")
|
||||
|
||||
print("Waiting for the next retrieval action...")
|
||||
|
||||
time.sleep(1) # Time here is in seconds.
|
||||
|
||||
def load_data(data):
|
||||
mydb = database_connect()
|
||||
if mydb.is_connected():
|
||||
mycursor = mydb.cursor()
|
||||
|
||||
# Here you need to adjust the correct column names and data formats based on the API response
|
||||
insert_query = """
|
||||
INSERT INTO goodgarden.relative_humidity_events (timestamp, gateway_receive_time, device, value)
|
||||
VALUES (%s, %s, %s, %s)
|
||||
"""
|
||||
for record in data['results']:
|
||||
timestamp = record.get('timestamp', '')
|
||||
gateway_receive_time = record.get('gateway_receive_time', '')
|
||||
device = record.get('device', '')
|
||||
value = record.get('value', '')
|
||||
|
||||
print(f"Inserting data: timestamp={timestamp}, gateway_receive_time={gateway_receive_time}, device={device}, value={value}")
|
||||
|
||||
# Execute the query
|
||||
mycursor.execute(insert_query, (timestamp, gateway_receive_time, device, value))
|
||||
|
||||
# Commit the changes
|
||||
mydb.commit()
|
||||
|
||||
# Close cursor and connection
|
||||
mycursor.close()
|
||||
mydb.close()
|
||||
|
||||
print("Data inserted into the database.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
url = "https://garden.inajar.nl/api/relative_humidity_events/?format=json"
|
||||
access_token = "33bb3b42452306c58ecedc3c86cfae28ba22329c"
|
||||
|
||||
# You can change the repeat_count to control how many times you want to repeat the process
|
||||
repeat_count = 10
|
||||
|
||||
fetch_and_display_all(url, access_token, repeat_count)
|
||||
@@ -1,63 +0,0 @@
|
||||
import requests
|
||||
import time
|
||||
|
||||
from db_connect import database_connect
|
||||
|
||||
def fetch_and_display_all(url, access_token, repeat_count=5):
|
||||
for _ in range(repeat_count):
|
||||
try:
|
||||
headers = {
|
||||
"Authorization": f"Token {access_token}"
|
||||
}
|
||||
response = requests.get(url, headers=headers)
|
||||
response.raise_for_status()
|
||||
|
||||
data = response.json()
|
||||
print(f"Data from {url}:")
|
||||
print(data)
|
||||
load_data(data)
|
||||
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"Error fetching data from {url}: {e}")
|
||||
|
||||
print("Waiting for the next retrieval action...")
|
||||
|
||||
time.sleep(1) # Time here is in seconds.
|
||||
|
||||
def load_data(data):
|
||||
mydb = database_connect()
|
||||
if mydb.is_connected():
|
||||
mycursor = mydb.cursor()
|
||||
|
||||
# Here you need to adjust the correct column names and data formats based on the API response
|
||||
insert_query = """
|
||||
INSERT INTO goodgarden.soil_electric_conductivity_events (timestamp, gateway_receive_time, device, value)
|
||||
VALUES (%s, %s, %s, %s)
|
||||
"""
|
||||
for record in data['results']:
|
||||
timestamp = record.get('timestamp', '')
|
||||
gateway_receive_time = record.get('gateway_receive_time', '')
|
||||
device = record.get('device', '')
|
||||
value = record.get('value', '')
|
||||
|
||||
print(f"Inserting data: timestamp={timestamp}, gateway_receive_time={gateway_receive_time}, device={device}, value={value}")
|
||||
|
||||
# Execute the query
|
||||
mycursor.execute(insert_query, (timestamp, gateway_receive_time, device, value))
|
||||
|
||||
# Commit the changes
|
||||
mydb.commit()
|
||||
|
||||
# Close cursor and connection
|
||||
mycursor.close()
|
||||
mydb.close()
|
||||
|
||||
print("Data inserted into the database.")
|
||||
if __name__ == "__main__":
|
||||
url = "https://garden.inajar.nl/api/soil_electric_conductivity_events/?format=json"
|
||||
access_token = "33bb3b42452306c58ecedc3c86cfae28ba22329c" # Replace this with your actual access token
|
||||
|
||||
# You can change the repeat_count to control how many times you want to repeat the process
|
||||
repeat_count = 10
|
||||
|
||||
fetch_and_display_all(url, access_token, repeat_count)
|
||||
@@ -1,66 +0,0 @@
|
||||
import requests
|
||||
import time
|
||||
|
||||
from db_connect import database_connect
|
||||
|
||||
def fetch_and_display_all(url, access_token, repeat_count=5):
|
||||
for _ in range(repeat_count):
|
||||
try:
|
||||
headers = {
|
||||
"Authorization": f"Token {access_token}"
|
||||
}
|
||||
response = requests.get(url, headers=headers)
|
||||
response.raise_for_status()
|
||||
|
||||
data = response.json()
|
||||
print(f"Data from {url}:")
|
||||
print(data)
|
||||
load_data(data)
|
||||
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"Error fetching data from {url}: {e}")
|
||||
|
||||
print("Waiting for the next retrieval action...")
|
||||
|
||||
time.sleep(1) # Time here is in seconds.
|
||||
|
||||
|
||||
def load_data(data):
|
||||
mydb = database_connect()
|
||||
if mydb.is_connected():
|
||||
mycursor = mydb.cursor()
|
||||
|
||||
# Here you need to adjust the correct column names and data formats based on the API response
|
||||
insert_query = """
|
||||
INSERT INTO goodgarden.soil_temperature_events (timestamp, gateway_receive_time, device, value)
|
||||
VALUES (%s, %s, %s, %s)
|
||||
"""
|
||||
for record in data['results']:
|
||||
timestamp = record.get('timestamp', '')
|
||||
gateway_receive_time = record.get('gateway_receive_time', '')
|
||||
device = record.get('device', '')
|
||||
value = record.get('value', '')
|
||||
|
||||
print(f"Inserting data: timestamp={timestamp}, gateway_receive_time={gateway_receive_time}, device={device}, value={value}")
|
||||
|
||||
# Execute the query
|
||||
mycursor.execute(insert_query, (timestamp, gateway_receive_time, device, value))
|
||||
|
||||
# Commit the changes
|
||||
mydb.commit()
|
||||
|
||||
# Close cursor and connection
|
||||
mycursor.close()
|
||||
mydb.close()
|
||||
|
||||
print("Data inserted into the database.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
url = "https://garden.inajar.nl/api/soil_relative_permittivity_events/?format=json"
|
||||
access_token = "33bb3b42452306c58ecedc3c86cfae28ba22329c"
|
||||
# You can change the repeat_count to control how many times you want to repeat the process
|
||||
repeat_count = 10
|
||||
|
||||
# fetch_and_display_all(urls, access_token)
|
||||
|
||||
fetch_and_display_all(url, access_token, repeat_count)
|
||||
@@ -1,65 +0,0 @@
|
||||
import requests
|
||||
import time
|
||||
|
||||
|
||||
from db_connect import database_connect
|
||||
|
||||
def fetch_and_display_all(url, access_token, repeat_count=5):
|
||||
for _ in range(repeat_count):
|
||||
|
||||
try:
|
||||
headers = {
|
||||
"Authorization": f"Token {access_token}"
|
||||
}
|
||||
response = requests.get(url, headers=headers)
|
||||
response.raise_for_status()
|
||||
|
||||
data = response.json()
|
||||
print(f"Data from {url}:")
|
||||
print(data)
|
||||
load_data(data)
|
||||
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"Error fetching data from {url}: {e}")
|
||||
|
||||
print("Waiting for the next retrieval action...")
|
||||
|
||||
time.sleep(1) # Time here is in seconds.
|
||||
|
||||
def load_data(data):
|
||||
mydb = database_connect()
|
||||
if mydb.is_connected():
|
||||
mycursor = mydb.cursor()
|
||||
|
||||
# Here you need to adjust the correct column names and data formats based on the API response
|
||||
insert_query = """
|
||||
INSERT INTO goodgarden.soil_temperature_events (timestamp, gateway_receive_time, device, value)
|
||||
VALUES (%s, %s, %s, %s)
|
||||
"""
|
||||
for record in data['results']:
|
||||
timestamp = record.get('timestamp', '')
|
||||
gateway_receive_time = record.get('gateway_receive_time', '')
|
||||
device = record.get('device', '')
|
||||
value = record.get('value', '')
|
||||
|
||||
print(f"Inserting data: timestamp={timestamp}, gateway_receive_time={gateway_receive_time}, device={device}, value={value}")
|
||||
|
||||
# Execute the query
|
||||
mycursor.execute(insert_query, (timestamp, gateway_receive_time, device, value))
|
||||
|
||||
# Commit the changes
|
||||
mydb.commit()
|
||||
|
||||
# Close cursor and connection
|
||||
mycursor.close()
|
||||
mydb.close()
|
||||
|
||||
print("Data inserted into the database.")
|
||||
if __name__ == "__main__":
|
||||
url = "https://garden.inajar.nl/api/soil_temperature_events/?format=json"
|
||||
access_token = "33bb3b42452306c58ecedc3c86cfae28ba22329c" # Replace this with your actual access token
|
||||
|
||||
# You can change the repeat_count to control how many times you want to repeat the process
|
||||
repeat_count = 10
|
||||
|
||||
fetch_and_display_all(url, access_token, repeat_count)
|
||||
@@ -1,32 +1,26 @@
|
||||
@import url("https://fonts.googleapis.com/css2?family=Akaya+Kanadaka&display=swap");
|
||||
@import url("https://fonts.googleapis.com/css2?family=Afacad:ital,wght@0,400..700;1,400..700&display=swap");
|
||||
h1, h2, h3, h4, h5 {
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5 {
|
||||
font-family: "Akaya Kanadaka", system-ui;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
p, td {
|
||||
p,
|
||||
td {
|
||||
font-family: "Afacad", sans-serif;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.containers-articles, body .mainContainer .mainBorder .content .kant-rechts #sensor-2, body .mainContainer .mainBorder .content .kant-links #sensor-1, body .mainContainer .mainBorder .content .kant-links #planten td article {
|
||||
height: 7rem;
|
||||
width: 10rem;
|
||||
padding: 0.6rem;
|
||||
margin: 0.1rem;
|
||||
margin-left: 2rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border: solid 3px rgb(171, 211, 174);
|
||||
border-radius: 40px;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
background-color: white;
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
body {
|
||||
background-image: url("../images/achtergrond.png");
|
||||
background: linear-gradient(rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0.5)), url("../images/achtergrond.png");
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
@@ -40,7 +34,7 @@ body {
|
||||
body .mainContainer {
|
||||
width: 85vw;
|
||||
height: 38rem;
|
||||
background-color: rgba(255, 255, 255, 0.95);
|
||||
background-color: rgba(255, 255, 255, 0.85);
|
||||
border-radius: 40px;
|
||||
padding: 2rem;
|
||||
}
|
||||
@@ -81,6 +75,7 @@ body .mainContainer .mainBorder #sectie-1 .parent-algemeen-overzicht {
|
||||
border-radius: 40px;
|
||||
padding: 1rem;
|
||||
margin-top: 1rem;
|
||||
background-color: white;
|
||||
}
|
||||
body .mainContainer .mainBorder #sectie-1 .parent-algemeen-overzicht .algemeen-overzicht {
|
||||
border: solid 2px rgb(171, 211, 174);
|
||||
@@ -101,6 +96,7 @@ body .mainContainer .mainBorder #sectie-1 .grafiek {
|
||||
border-radius: 40px;
|
||||
padding: 1rem;
|
||||
position: relative;
|
||||
background-color: white;
|
||||
}
|
||||
body .mainContainer .mainBorder #sectie-1 .grafiek .grafiek-innerbox {
|
||||
border: solid 2px rgb(171, 211, 174);
|
||||
@@ -133,6 +129,20 @@ body .mainContainer .mainBorder .content .kant-links #planten {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
body .mainContainer .mainBorder .content .kant-links #planten td article {
|
||||
height: 7rem;
|
||||
width: 10rem;
|
||||
padding: 0.6rem;
|
||||
margin: 0.1rem;
|
||||
margin-left: 2rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border: solid 3px rgb(171, 211, 174);
|
||||
border-radius: 40px;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
body .mainContainer .mainBorder .content .kant-links #planten td article #toevoegen {
|
||||
height: 5rem;
|
||||
width: 5rem;
|
||||
@@ -143,15 +153,8 @@ body .mainContainer .mainBorder .content .kant-links #planten td article h2 {
|
||||
body .mainContainer .mainBorder .content .kant-links #planten td article:hover {
|
||||
background-color: lightgray;
|
||||
}
|
||||
body .mainContainer .mainBorder .content .kant-links #sensor-1 {
|
||||
border: none;
|
||||
border-radius: 40px 0px 0px 40px;
|
||||
width: 30vw;
|
||||
margin-top: 10vh;
|
||||
}
|
||||
body .mainContainer .mainBorder .content .kant-rechts {
|
||||
grid-column: 3;
|
||||
margin-right: 2rem;
|
||||
}
|
||||
body .mainContainer .mainBorder .content .kant-rechts #metingen {
|
||||
border: solid 3px rgb(171, 211, 174);
|
||||
@@ -169,16 +172,12 @@ body .mainContainer .mainBorder .content .kant-rechts #metingen #main-waardes ta
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
}
|
||||
body .mainContainer .mainBorder .content .kant-rechts #sensor-2 {
|
||||
border-radius: 0px 40px 40px 0px;
|
||||
width: 30vw;
|
||||
margin-top: 10vh;
|
||||
}
|
||||
body .mainContainer .mainBorder .grid-column-2 {
|
||||
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.5);
|
||||
border-radius: 40px;
|
||||
padding: 1rem;
|
||||
margin: 3.25rem 1rem 1.25rem 1rem;
|
||||
background-color: white;
|
||||
}
|
||||
body .mainContainer .mainBorder .grid-column-2 .grid-2-child {
|
||||
border: solid 2px rgb(171, 211, 174);
|
||||
@@ -189,9 +188,17 @@ body .mainContainer .mainBorder .grid-column-2 .grid-2-child .parent-table {
|
||||
padding: 1.5rem 2rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
gap: 2.5rem;
|
||||
justify-content: space-around;
|
||||
height: 90%;
|
||||
}
|
||||
body .mainContainer .mainBorder .grid-column-2 .grid-2-child .parent-table table tr td {
|
||||
font-size: 1.05rem;
|
||||
}
|
||||
body .mainContainer .mainBorder .grid-column-2 .grid-2-child .parent-table .kas-table-1 tr td {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
body .mainContainer .mainBorder .grid-column-2 .grid-2-child .parent-table .kas-table-2 {
|
||||
position: relative;
|
||||
}
|
||||
@@ -211,7 +218,6 @@ body .mainContainer .mainBorder .grid-column-2 .grid-2-child .parent-table .kas-
|
||||
top: -20px;
|
||||
}
|
||||
|
||||
/* Divider */
|
||||
.divider {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
@@ -221,7 +227,6 @@ body .mainContainer .mainBorder .grid-column-2 .grid-2-child .parent-table .kas-
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
/* The Modal (background) */
|
||||
.modal {
|
||||
display: none;
|
||||
position: fixed;
|
||||
@@ -234,17 +239,168 @@ body .mainContainer .mainBorder .grid-column-2 .grid-2-child .parent-table .kas-
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
width: 30vw;
|
||||
height: auto;
|
||||
border: solid 2px black;
|
||||
border: solid 2px #abd3ae;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.modal .close {
|
||||
color: #aaa;
|
||||
float: right;
|
||||
font-size: 1.75rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
.modal .close:hover, .modal .close:active {
|
||||
|
||||
.modal .close:hover,
|
||||
.modal .close:active {
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#myModal select,
|
||||
#myModal input {
|
||||
width: calc(100% - 20px);
|
||||
padding: 10px;
|
||||
margin-bottom: 15px;
|
||||
border: 2px solid #abd3ae;
|
||||
border-radius: 5px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#myModal .knop {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
#myModal button {
|
||||
width: 48%;
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
#myModal .knop-container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
#myModal .knop-container input,
|
||||
#myModal .knop-container button {
|
||||
flex: 1;
|
||||
margin: 0 5px;
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#myModal input[type=text],
|
||||
#myModal select {
|
||||
border: 2px solid #abd3ae;
|
||||
padding: 10px;
|
||||
border-radius: 17px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#myModal input[type=submit],
|
||||
#myModal button {
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 15px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#myModal input[type=submit] {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
#myModal button {
|
||||
background-color: white;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.toevoeging {
|
||||
background: linear-gradient(45deg, #abd3ae, #2ecc71);
|
||||
}
|
||||
|
||||
.annulatie-knop {
|
||||
background: linear-gradient(45deg, #ffcc00, #ff6600);
|
||||
}
|
||||
|
||||
#myModal button:hover {
|
||||
background: linear-gradient(45deg, #abd3ae, #fff);
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.modal .close {
|
||||
color: #aaa;
|
||||
float: right;
|
||||
font-size: 1.75rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.modal .close:hover,
|
||||
.modal .close:active {
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.switch-container {
|
||||
display: flex;
|
||||
align-items: end;
|
||||
}
|
||||
|
||||
.switch {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 60px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.switch input {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.slider {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: #ccc;
|
||||
border-radius: 34px;
|
||||
transition: 0.4s;
|
||||
}
|
||||
|
||||
.slider:before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
height: 26px;
|
||||
width: 26px;
|
||||
left: 4px;
|
||||
bottom: 4px;
|
||||
background-color: white;
|
||||
border-radius: 50%;
|
||||
transition: 0.4s;
|
||||
}
|
||||
|
||||
input:checked + .slider {
|
||||
background-color: #2ecc71;
|
||||
}
|
||||
|
||||
input:checked + .slider:before {
|
||||
transform: translateX(26px);
|
||||
}
|
||||
|
||||
.rechterkant {
|
||||
display: flex;
|
||||
justify-content: end;
|
||||
}
|
||||
|
||||
.plant-container,
|
||||
#modalButton {
|
||||
background-color: white;
|
||||
}/*# sourceMappingURL=style.css.map */
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"sources":["style.scss","style.css"],"names":[],"mappings":"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","file":"style.css"}
|
||||
{"version":3,"sources":["style.scss","style.css"],"names":[],"mappings":"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","file":"style.css"}
|
||||
@@ -1,17 +1,17 @@
|
||||
$primary-color: rgb(171, 211, 174);
|
||||
$secondary-color: rgb(143, 188, 143);
|
||||
|
||||
@import url('https://fonts.googleapis.com/css2?family=Akaya+Kanadaka&display=swap');
|
||||
@import url('https://fonts.googleapis.com/css2?family=Afacad:ital,wght@0,400..700;1,400..700&display=swap');
|
||||
@import url("https://fonts.googleapis.com/css2?family=Akaya+Kanadaka&display=swap");
|
||||
@import url("https://fonts.googleapis.com/css2?family=Afacad:ital,wght@0,400..700;1,400..700&display=swap");
|
||||
|
||||
$font-titels: "Akaya Kanadaka", system-ui;
|
||||
|
||||
$font-text: "Afacad", sans-serif;
|
||||
|
||||
@mixin flexbox
|
||||
@mixin flexbox-center
|
||||
{
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
@mixin groene-border
|
||||
@@ -34,37 +34,31 @@ $font-text: "Afacad", sans-serif;
|
||||
border-radius: 35px;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5
|
||||
{
|
||||
font-family: $font-titels;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
p, td
|
||||
p,
|
||||
td
|
||||
{
|
||||
font-family: $font-text;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.containers-articles
|
||||
a
|
||||
{
|
||||
height: 7rem;
|
||||
width: 10rem;
|
||||
padding: .6rem;
|
||||
margin: 0.1rem;
|
||||
margin-left: 2rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border: solid 3px $primary-color;
|
||||
border-radius: 40px;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
background-color: white;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
body
|
||||
{
|
||||
background-image: url("../images/achtergrond.png");
|
||||
background: linear-gradient(rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0.5)), url("../images/achtergrond.png");
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
@@ -79,7 +73,7 @@ body
|
||||
{
|
||||
width: 85vw;
|
||||
height: 38rem;
|
||||
background-color: rgb(255, 255, 255, 95%);
|
||||
background-color: rgb(255, 255, 255, 85%);
|
||||
border-radius: 40px;
|
||||
padding: 2rem;
|
||||
|
||||
@@ -131,14 +125,14 @@ body
|
||||
@include border-radius;
|
||||
padding: 1rem;
|
||||
margin-top: 1rem;
|
||||
|
||||
background-color: white;
|
||||
|
||||
.algemeen-overzicht
|
||||
{
|
||||
@include groene-border;
|
||||
@include inner-border-radius;
|
||||
font-size: 1.25rem;
|
||||
padding: .5rem 1rem;
|
||||
padding: 0.5rem 1rem;
|
||||
|
||||
.table-informatie-kas
|
||||
{
|
||||
@@ -160,6 +154,7 @@ body
|
||||
@include border-radius;
|
||||
padding: 1rem;
|
||||
position: relative;
|
||||
background-color: white;
|
||||
|
||||
.grafiek-innerbox
|
||||
{
|
||||
@@ -179,7 +174,7 @@ body
|
||||
|
||||
canvas
|
||||
{
|
||||
// Zorgt ervoor dat de grafiek precies in het midden komt
|
||||
// Zorgt ervoor dat de grafiek precies in eht midden komt
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
@@ -187,8 +182,8 @@ body
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.content
|
||||
{
|
||||
display: grid;
|
||||
@@ -210,7 +205,18 @@ body
|
||||
{
|
||||
article
|
||||
{
|
||||
@extend .containers-articles;
|
||||
height: 7rem;
|
||||
width: 10rem;
|
||||
padding: 0.6rem;
|
||||
margin: 0.1rem;
|
||||
margin-left: 2rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border: solid 3px $primary-color;
|
||||
border-radius: 40px;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
|
||||
#toevoegen
|
||||
{
|
||||
@@ -227,33 +233,18 @@ body
|
||||
{
|
||||
background-color: lightgray;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#sensor
|
||||
{
|
||||
&-1
|
||||
{
|
||||
@extend .containers-articles;
|
||||
border: none;
|
||||
border-radius: 40px 0px 0px 40px;
|
||||
width: 30vw;
|
||||
margin-top: 10vh;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-rechts
|
||||
{
|
||||
grid-column: 3;
|
||||
margin-right: 2rem;
|
||||
// margin-right: 2rem;
|
||||
|
||||
#metingen
|
||||
{
|
||||
|
||||
border: solid 3px $primary-color;
|
||||
border-radius: 40px;
|
||||
|
||||
@@ -261,7 +252,7 @@ body
|
||||
{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: .5rem;
|
||||
padding: 0.5rem;
|
||||
padding-bottom: 0;
|
||||
width: 100%;
|
||||
|
||||
@@ -273,17 +264,6 @@ body
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#sensor
|
||||
{
|
||||
&-2
|
||||
{
|
||||
@extend .containers-articles;
|
||||
border-radius: 0px 40px 40px 0px;
|
||||
width: 30vw;
|
||||
margin-top: 10vh;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -294,6 +274,7 @@ body
|
||||
@include border-radius;
|
||||
padding: 1rem;
|
||||
margin: 3.25rem 1rem 1.25rem 1rem;
|
||||
background-color: white;
|
||||
|
||||
.grid-2-child
|
||||
{
|
||||
@@ -301,14 +282,13 @@ body
|
||||
@include inner-border-radius;
|
||||
height: 100%;
|
||||
|
||||
|
||||
.parent-table
|
||||
{
|
||||
padding: 1.5rem 2rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
// align-items: stretch;
|
||||
// gap: 2.5rem;
|
||||
align-items: stretch;
|
||||
gap: 2.5rem;
|
||||
justify-content: space-around;
|
||||
height: 90%;
|
||||
|
||||
@@ -318,7 +298,7 @@ body
|
||||
{
|
||||
td
|
||||
{
|
||||
// font-size: 1.05rem;
|
||||
font-size: 1.05rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -329,7 +309,7 @@ body
|
||||
{
|
||||
td
|
||||
{
|
||||
// font-size: 1.25rem;
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -360,16 +340,13 @@ body
|
||||
top: -20px;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Divider */
|
||||
.divider {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
@@ -379,10 +356,7 @@ body
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
/* The Modal (background) */
|
||||
|
||||
.modal
|
||||
{
|
||||
.modal {
|
||||
display: none;
|
||||
position: fixed;
|
||||
z-index: 999;
|
||||
@@ -394,22 +368,168 @@ body
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
width: 30vw;
|
||||
height: auto;
|
||||
border: solid 2px black;
|
||||
border: solid 2px #abd3ae;
|
||||
border-radius: 10px;
|
||||
|
||||
.close
|
||||
{
|
||||
}
|
||||
.modal .close {
|
||||
color: #aaa;
|
||||
float: right;
|
||||
font-size: 1.75rem;
|
||||
font-weight: bold;
|
||||
|
||||
&:hover,
|
||||
&:active
|
||||
{
|
||||
}
|
||||
.modal .close:hover,
|
||||
.modal .close:active {
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#myModal select,
|
||||
#myModal input {
|
||||
width: calc(100% - 20px);
|
||||
padding: 10px;
|
||||
margin-bottom: 15px;
|
||||
border: 2px solid #abd3ae;
|
||||
border-radius: 5px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#myModal .knop {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
#myModal button {
|
||||
width: 48%;
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
#myModal .knop-container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
#myModal .knop-container input,
|
||||
#myModal .knop-container button {
|
||||
flex: 1;
|
||||
margin: 0 5px;
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#myModal input[type="text"],
|
||||
#myModal select {
|
||||
border: 2px solid #abd3ae;
|
||||
padding: 10px;
|
||||
border-radius: 17px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#myModal input[type="submit"],
|
||||
#myModal button {
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 15px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#myModal input[type="submit"] {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
#myModal button {
|
||||
background-color: white;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.toevoeging {
|
||||
background: linear-gradient(45deg, #abd3ae, #2ecc71);
|
||||
}
|
||||
|
||||
.annulatie-knop {
|
||||
background: linear-gradient(45deg, #ffcc00, #ff6600);
|
||||
}
|
||||
|
||||
#myModal button:hover {
|
||||
background: linear-gradient(45deg, #abd3ae, #fff);
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.modal .close {
|
||||
color: #aaa;
|
||||
float: right;
|
||||
font-size: 1.75rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.modal .close:hover,
|
||||
.modal .close:active {
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.switch-container {
|
||||
display: flex;
|
||||
align-items: end;
|
||||
}
|
||||
|
||||
.switch {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 60px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.switch input {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.slider {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: #ccc;
|
||||
border-radius: 34px;
|
||||
transition: 0.4s;
|
||||
}
|
||||
|
||||
.slider:before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
height: 26px;
|
||||
width: 26px;
|
||||
left: 4px;
|
||||
bottom: 4px;
|
||||
background-color: white;
|
||||
border-radius: 50%;
|
||||
transition: 0.4s;
|
||||
}
|
||||
|
||||
input:checked + .slider {
|
||||
background-color: #2ecc71;
|
||||
}
|
||||
|
||||
input:checked + .slider:before {
|
||||
transform: translateX(26px);
|
||||
}
|
||||
|
||||
.rechterkant {
|
||||
display: flex;
|
||||
justify-content: end;
|
||||
}
|
||||
|
||||
.plant-container,
|
||||
#modalButton
|
||||
{
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
115
src/js/main.js
@@ -1,115 +0,0 @@
|
||||
const { ipcRenderer } = require("electron");
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () =>
|
||||
{
|
||||
ipcRenderer.send('request-update-temp', ['some', 'arguments']);
|
||||
|
||||
ipcRenderer.on('update-temp-result', (event, newTemperature) => {
|
||||
if (newTemperature === 'error') {
|
||||
console.error('Er is een fout opgetreden bij het ophalen van de nieuwe temperatuur');
|
||||
} else {
|
||||
document.getElementById('bodem-temperatuur').textContent = newTemperature;
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
function openModal()
|
||||
{
|
||||
const modal = document.getElementById("myModal");
|
||||
const button = document.getElementById("modalButton");
|
||||
const close = document.getElementsByClassName("close")[0];
|
||||
|
||||
// Toon de modal wanneer op de knop wordt geklikt
|
||||
button.onclick = function()
|
||||
{
|
||||
modal.style.display = "block";
|
||||
}
|
||||
|
||||
// Sluit de modal wanneer op het 'sluiten' icoon wordt geklikt
|
||||
close.onclick = function()
|
||||
{
|
||||
modal.style.display = "none";
|
||||
}
|
||||
|
||||
// Sluit de modal wanneer buiten de modal wordt geklikt
|
||||
window.onclick = function(event)
|
||||
{
|
||||
if (event.target == modal)
|
||||
{
|
||||
modal.style.display = "none";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* --- Functie om de grafiek te tekenen. Enigste belangrijke is de eerste 2 "const" arrays "data" & "xLabels".
|
||||
*/
|
||||
function drawLineChart()
|
||||
{
|
||||
/*Dit is de data die getoond wordt als "punt" op de grafiek. 20 = y20 / x20, 50 = y50 / x50 enzovoort... De array "data" & "xLabels" moeten beide evenveel array items hebben!!*/
|
||||
const data = [20, 50, 60, 45, 50, 100, 70, 60, 65, 0, 85, 0];
|
||||
const xLabels = ["", "", "", "", "", 6, "", "", "", "", "", 12];
|
||||
|
||||
const yLabels = ["", 20, "", 40, "", 60, "", 80, "", 100]; /*NIET VERANDEREN!!!*/
|
||||
|
||||
const canvas = document.getElementById("myCanvas");
|
||||
const ctx = canvas.getContext("2d");
|
||||
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
const padding = 35; // Increased padding for Y labels
|
||||
const graphWidth = canvas.width - padding * 2;
|
||||
const graphHeight = canvas.height - padding * 2;
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(padding, padding);
|
||||
ctx.lineTo(padding, canvas.height - padding);
|
||||
ctx.lineTo(canvas.width - padding, canvas.height - padding);
|
||||
ctx.stroke();
|
||||
|
||||
// Set the color of the line
|
||||
ctx.strokeStyle = "rgb(143, 188, 143)";
|
||||
|
||||
const xIncrement = graphWidth / (xLabels.length - 1);
|
||||
const yIncrement = graphHeight / (yLabels.length - 1);
|
||||
|
||||
// Plot the data
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(padding, canvas.height - padding - (data[0] / 100) * graphHeight);
|
||||
|
||||
for (let i = 1; i < data.length; i++)
|
||||
{
|
||||
const xPos = padding + i * xIncrement;
|
||||
const yPos = canvas.height - padding - (data[i] / 100) * graphHeight;
|
||||
ctx.lineTo(xPos, yPos);
|
||||
}
|
||||
ctx.stroke();
|
||||
|
||||
// Draw Y labels
|
||||
ctx.fillStyle = "black";
|
||||
ctx.textAlign = "right"; // Align text to the right
|
||||
ctx.textBaseline = "middle"; // Center vertically
|
||||
|
||||
for (let i = 0; i < yLabels.length; i++)
|
||||
{
|
||||
if (yLabels[i] !== "")
|
||||
{
|
||||
const yPos = canvas.height - padding - i * yIncrement;
|
||||
ctx.fillText(yLabels[i], padding - 10, yPos);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw X labels
|
||||
ctx.textAlign = "center"; // Center horizontally for X labels
|
||||
for (let i = 0; i < xLabels.length; i++)
|
||||
{
|
||||
if (xLabels[i] !== "")
|
||||
{
|
||||
const xPos = padding + i * xIncrement;
|
||||
ctx.fillText(xLabels[i], xPos, canvas.height - padding + 20);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
drawLineChart();
|
||||
@@ -1,143 +0,0 @@
|
||||
class Plant {
|
||||
constructor(dataObject) {
|
||||
this.id = dataObject.id;
|
||||
this.plantNaam = dataObject.plantNaam;
|
||||
this.plantensoort = dataObject.plantensoort;
|
||||
this.plantGeteelt = dataObject.plantGeteelt;
|
||||
}
|
||||
}
|
||||
|
||||
class PlantGrid {
|
||||
constructor() {
|
||||
this.grid = [];
|
||||
this.cols = 2; // Number of columns
|
||||
this.rows = 4; // Number of rows (including the row for the "Add" button)
|
||||
|
||||
// Initialize the grid with null values
|
||||
for (let i = 0; i < this.rows; i++) {
|
||||
this.grid[i] = new Array(this.cols).fill(null);
|
||||
}
|
||||
|
||||
// Sample data
|
||||
const dataHardObject = [
|
||||
{
|
||||
"id": 1,
|
||||
"plantNaam": "Tomt",
|
||||
"plantensoort": "Groente",
|
||||
"plantGeteelt": 1
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"plantNaam": "Komkommer",
|
||||
"plantensoort": "Groente",
|
||||
"plantGeteelt": 1
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"plantNaam": "Appel",
|
||||
"plantensoort": "Groente",
|
||||
"plantGeteelt": 0
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"plantNaam": "KwamKwammer",
|
||||
"plantensoort": "Groente",
|
||||
"plantGeteelt": 1
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"plantNaam": ":p",
|
||||
"plantensoort": "Groente",
|
||||
"plantGeteelt": 1
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"plantNaam": ":3",
|
||||
"plantensoort": "Groente",
|
||||
"plantGeteelt": 1
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"plantNaam": "Groene",
|
||||
"plantensoort": "Groente",
|
||||
"plantGeteelt": 1
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"plantNaam": "test",
|
||||
"plantensoort": "Groente",
|
||||
"plantGeteelt": 0
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"plantNaam": "yippie",
|
||||
"plantensoort": "Groente",
|
||||
"plantGeteelt": 1
|
||||
}
|
||||
];
|
||||
|
||||
// Only save objects that have plantGeteelt as 1
|
||||
const filteredData = dataHardObject.filter(plantObject => plantObject.plantGeteelt === 1);
|
||||
|
||||
// Populate the grid with plant objects
|
||||
filteredData.slice(0, 8).forEach((plantObject, index) => {
|
||||
const plant = new Plant(plantObject);
|
||||
const col = index % this.cols;
|
||||
const row = Math.floor(index / this.cols);
|
||||
this.grid[row][col] = plant;
|
||||
});
|
||||
|
||||
|
||||
// Display the grid in the HTML table with id "planten"
|
||||
this.displayGrid();
|
||||
}
|
||||
|
||||
displayGrid() {
|
||||
const plantenTable = document.getElementById("planten");
|
||||
|
||||
let itemCount = 0; // Counter for the number of items in the grid
|
||||
|
||||
this.grid.forEach((row, rowIndex) => {
|
||||
const tr = document.createElement("tr");
|
||||
|
||||
row.forEach((plant, colIndex) => {
|
||||
const td = document.createElement("td");
|
||||
|
||||
if (itemCount < 8) {
|
||||
if (plant) {
|
||||
// Handle regular plant items
|
||||
const article = document.createElement("article");
|
||||
const img = article.appendChild(document.createElement("img"));
|
||||
img.src = "images/Icon awesome-apple-alt.png";
|
||||
const h2 = article.appendChild(document.createElement("h2"));
|
||||
h2.classList.add("plant-naam");
|
||||
h2.textContent = plant.plantNaam;
|
||||
|
||||
td.appendChild(article);
|
||||
itemCount++;
|
||||
} else if (rowIndex === this.rows -1 && colIndex === this.cols -1 && itemCount <= 7) {
|
||||
// Handle the "Add" button
|
||||
const article = document.createElement("article");
|
||||
const img = article.appendChild(document.createElement("img"));
|
||||
img.src = "images/Toevoegen.png";
|
||||
img.id = "toevoegen";
|
||||
img.alt = "Add";
|
||||
article.id = "modalButton";
|
||||
article.onclick = openModal;
|
||||
|
||||
td.appendChild(article);
|
||||
itemCount++;
|
||||
}
|
||||
}
|
||||
|
||||
tr.appendChild(td);
|
||||
});
|
||||
|
||||
plantenTable.appendChild(tr);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
const plantGrid = new PlantGrid();
|
||||
});
|
||||
@@ -1,109 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="stylesheet" href="../src/css/style.css" />
|
||||
<script src="../src/js/main.js" defer></script>
|
||||
<title>Informatie Kas</title>
|
||||
</head>
|
||||
<body>
|
||||
<section class="mainContainer">
|
||||
<article>
|
||||
<img src="../src/images/logo.png" class="goodgarden-logo">
|
||||
</article>
|
||||
<section class="mainBorder informatie-kas-main-container">
|
||||
<article>
|
||||
<h1 class="pagina-titel">Informatie Kas</h1>
|
||||
<section id="sectie-1">
|
||||
<article class="parent-algemeen-overzicht">
|
||||
<article class="algemeen-overzicht">
|
||||
<table class="table-informatie-kas">
|
||||
<tr class="tr-informatie-kas">
|
||||
<td>Dagen tot Oogst</td>
|
||||
<td>12</td>
|
||||
</tr>
|
||||
<tr class="tr-informatie-kas">
|
||||
<td>Dagen in Kas</td>
|
||||
<td>2</td>
|
||||
</tr>
|
||||
<tr class="tr-informatie-kas">
|
||||
<td>Tevredenheid</td>
|
||||
<td>80%</td>
|
||||
</tr>
|
||||
<tr class="tr-informatie-kas">
|
||||
<td>Aandachtspunten</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
</table>
|
||||
</article>
|
||||
</article>
|
||||
<article class="grafiek">
|
||||
<article class="grafiek-innerbox">
|
||||
<h2>Zonlicht</h2>
|
||||
<canvas
|
||||
id="myCanvas" class="canvas-informatie-kas" width="275" height="275"></canvas>
|
||||
</article>
|
||||
</article>
|
||||
</section>
|
||||
</article>
|
||||
<article class="grid-column-2">
|
||||
<article class="grid-2-child">
|
||||
<section class="parent-table">
|
||||
<table class="kas-table-1">
|
||||
<tr>
|
||||
<td>Aantal geplant:</td>
|
||||
<td>2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Succesvolle Oogst:</td>
|
||||
<td>2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Gefaalde Oogst:</td>
|
||||
<td>2</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table class="kas-table-2">
|
||||
<tr>
|
||||
<td>Warmste Maand:</td>
|
||||
<td>n.v.t.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>koudste Maand:</td>
|
||||
<td>December</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Gemiddelde Bodemtemp.:</td>
|
||||
<td id="bodem-temperatuur">2˚C</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Gemiddelde Uren Zonlicht:</td>
|
||||
<td id="battery_voltage">2u</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table class="kas-table-3">
|
||||
<tr>
|
||||
<td>Laatste Irrigatie:</td>
|
||||
<td>2u</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Aankomende Irrigatie:</td>
|
||||
<td>2u</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Laatste Bemesting</td>
|
||||
<td>2d</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Aankomende Bemesting:</td>
|
||||
<td>2w</td>
|
||||
</tr>
|
||||
</table>
|
||||
</section>
|
||||
</article>
|
||||
</article>
|
||||
</section>
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,14 +1,10 @@
|
||||
|
||||
// Deze spanningswaarden zijn relatief hoog, wat suggereert dat de batterijen van de sensoren goed opgeladen zijn. De meeste sensorapparaten gebruiken batterijen die een nominale spanning van ongeveer 3,7 volt hebben (typisch voor lithium-ion batterijen) en kunnen worden beschouwd als "volledig opgeladen" wanneer ze een spanning dicht bij of iets boven 4,1 volt bereiken
|
||||
"battery_voltage_events": [
|
||||
{ "battery_voltage_events": [
|
||||
{
|
||||
"timestamp": 1707825721,
|
||||
"gateway_receive_time": "2024-02-13T12:02:01Z",
|
||||
"device": 256,
|
||||
"value": 4.098901271820068
|
||||
// Volledig opgeladen: Rond 4.2 volt.
|
||||
// Nominale spanning: Ongeveer 3.7 volt.
|
||||
// Kritiek laag: Minder dan 3.0 volt.
|
||||
|
||||
},
|
||||
{
|
||||
"timestamp": 1707837460,
|
||||
@@ -44,7 +40,6 @@
|
||||
|
||||
|
||||
|
||||
// Fotosyntese??? (zonlicht)
|
||||
"par_events": [
|
||||
{
|
||||
"timestamp": 1707844638,
|
||||
@@ -63,7 +58,6 @@
|
||||
|
||||
|
||||
|
||||
// Luchtvochtigheid
|
||||
"relative_humidity_events": [
|
||||
{
|
||||
"timestamp": 1707844638,
|
||||
@@ -83,7 +77,6 @@
|
||||
|
||||
|
||||
|
||||
// De "soil_electric_conductivity_events" gegevens wijzen op metingen van de elektrische geleidbaarheid (EC) van de bodem, een indicator van de hoeveelheid oplosbare zouten of voedingsstoffen in de bodem. EC wordt gemeten in Siemens per meter (S/m) of, voor bodemmetingen, vaak in milliSiemens per centimeter (mS/cm). Een hogere EC-waarde duidt op een hogere concentratie van opgeloste zouten, wat belangrijk is voor het bepalen van de voedingsstatus van de bodem en het beheren van de bemesting voor optimale plantengroei.
|
||||
"soil_electric_conductivity_events": [
|
||||
{
|
||||
"timestamp": 1707851215,
|
||||
@@ -97,20 +90,17 @@
|
||||
|
||||
|
||||
|
||||
// In de context van bodemmetingen, geeft deze waarde inzicht in het vochtgehalte van de bodem, omdat water een relatief hoge diëlektrische constante heeft in vergelijking met droge bodem of lucht.
|
||||
"soil_relative_permittivity_events": [
|
||||
{
|
||||
"timestamp": 1707851215,
|
||||
"gateway_receive_time": "2024-02-13T19:06:55Z",
|
||||
"device": 322,
|
||||
"value": 1.52
|
||||
// Een waarde van 1.52 is relatief laag en suggereert dat de bodem droog kan zijn op het moment van meting. Ter referentie, de diëlektrische constante van lucht is ongeveer 1, terwijl water een diëlektrische constante heeft van ongeveer 80 bij kamertemperatuur.
|
||||
}
|
||||
],
|
||||
|
||||
|
||||
|
||||
//De "soil_temperature_events" gegevens bevatten informatie over de temperatuur van de bodem op een specifiek tijdstip. De waarde geeft de temperatuur van de bodem aan in graden Celsius (°C).
|
||||
"soil_temperature_events": [
|
||||
{
|
||||
"timestamp": 1707851215,
|
||||
223
src/py/script/battery_voltage_events.py
Normal file
@@ -0,0 +1,223 @@
|
||||
import mysql.connector
|
||||
import requests
|
||||
from datetime import datetime, timezone, timedelta
|
||||
import time
|
||||
|
||||
# Function to make a connection to the database
|
||||
def database_connect():
|
||||
return mysql.connector.connect(
|
||||
host="localhost",
|
||||
user="root",
|
||||
password="",
|
||||
database="goodgarden"
|
||||
)
|
||||
|
||||
# Functie voor het aanmaken van gegevens in de database
|
||||
def create_data(url, access_token, repeat_count=5):
|
||||
for _ in range(repeat_count):
|
||||
try:
|
||||
headers = {"Authorization": f"Token {access_token}"}
|
||||
response = requests.get(url, headers=headers)
|
||||
response.raise_for_status()
|
||||
|
||||
data = response.json()
|
||||
print(f"Data from {url}:\n")
|
||||
|
||||
# Check if data is a list (records directly under the root)
|
||||
if isinstance(data, list):
|
||||
records = data
|
||||
elif isinstance(data, dict) and 'results' in data:
|
||||
records = data['results']
|
||||
else:
|
||||
print(f"Unexpected data format received: {data}")
|
||||
continue
|
||||
|
||||
for record in records:
|
||||
# Now, record is assumed to be a dictionary
|
||||
timestamp = record.get('timestamp', '')
|
||||
gateway_receive_time = record.get('gateway_receive_time', '')
|
||||
device = record.get('device', '')
|
||||
value = record.get('value', '')
|
||||
|
||||
print(f"\nInserted data: Timestamp: {timestamp}, Device: {device}, Battery Voltage: {value}V\n")
|
||||
if float(value) < 3.0:
|
||||
print("Waarschuwing: Batterijspanning is lager dan 3.0 volt. Opladen aanbevolen.\n")
|
||||
# Controleer of de batterijspanning hoger is dan 4.2 volt en geef een melding
|
||||
elif float(value) > 4.2:
|
||||
print("Melding: Batterijspanning is hoger dan 4.2 volt. Batterij is vol.\n")
|
||||
else:
|
||||
print("Melding: Batterijspanning is binnen het gewenste bereik.\n\n")
|
||||
|
||||
# Insert data into the database
|
||||
insert_data(record)
|
||||
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"Error fetching data from {url}: {e}")
|
||||
|
||||
print("Waiting for the next create action...\n")
|
||||
time.sleep(1)
|
||||
|
||||
# Functie voor het invoegen van gegevens in de database
|
||||
def insert_data(record):
|
||||
mydb = database_connect()
|
||||
if mydb.is_connected():
|
||||
mycursor = mydb.cursor()
|
||||
|
||||
# Hier moet je de juiste kolomnamen en gegevensindeling aanpassen op basis van de API-respons
|
||||
insert_query = """
|
||||
INSERT INTO goodgarden.battery_voltage_events (timestamp, gateway_receive_time, device, value)
|
||||
VALUES (%s, %s, %s, %s)
|
||||
"""
|
||||
# Pas dit aan op basis van de werkelijke structuur van de JSON
|
||||
timestamp = record.get('timestamp', '')
|
||||
gateway_receive_time = record.get('gateway_receive_time', '')
|
||||
device = record.get('device', '')
|
||||
value = record.get('value', '')
|
||||
|
||||
print(f"Inserting data: timestamp={timestamp}, gateway_receive_time={gateway_receive_time}, device={device}, value={value}") # Print de ingevoerde gegevens
|
||||
|
||||
# Voer de query uit
|
||||
mycursor.execute(insert_query, (timestamp, gateway_receive_time, device, value))
|
||||
|
||||
# Bevestig de wijzigingen
|
||||
mydb.commit()
|
||||
|
||||
# Sluit cursor en verbinding
|
||||
mycursor.close()
|
||||
mydb.close()
|
||||
|
||||
print("Data inserted into the database.")
|
||||
|
||||
# Functie voor het lezen van gegevens uit de database
|
||||
def read_data(url, access_token, repeat_count=5):
|
||||
for _ in range(repeat_count):
|
||||
try:
|
||||
headers = {"Authorization": f"Token {access_token}"}
|
||||
response = requests.get(url, headers=headers)
|
||||
response.raise_for_status()
|
||||
|
||||
data = response.json()
|
||||
print(f"Data from {url}:\n")
|
||||
|
||||
for record in data['results']:
|
||||
timestamp = record.get('timestamp', '')
|
||||
device = record.get('device', '')
|
||||
value = record.get('value', '')
|
||||
print(f"Timestamp: {timestamp}, Device: {device}, Battery Voltage: {value}V\n")
|
||||
|
||||
if float(value) < 3.0:
|
||||
print("Waarschuwing: Batterijspanning is lager dan 3.0 volt. Opladen aanbevolen.\n")
|
||||
# Controleer of de batterijspanning hoger is dan 4.2 volt en geef een melding
|
||||
elif float(value) > 4.2:
|
||||
print("Melding: Batterijspanning is hoger dan 4.2 volt. Batterij is vol.\n")
|
||||
else:
|
||||
print("Melding: Batterijspanning is binnen het gewenste bereik.\n\n")
|
||||
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"Error fetching data from {url}: {e}")
|
||||
|
||||
print("Waiting for the next read action...\n")
|
||||
time.sleep(300)
|
||||
|
||||
# Functie voor het bijwerken van gegevens in de database
|
||||
def update_data(record_id):
|
||||
try:
|
||||
mydb = database_connect()
|
||||
|
||||
if mydb.is_connected():
|
||||
mycursor = mydb.cursor()
|
||||
|
||||
# Controleer of het record bestaat voordat je het bijwerkt
|
||||
mycursor.execute("SELECT * FROM goodgarden.battery_voltage_events WHERE id = %s", (record_id,))
|
||||
existing_record = mycursor.fetchone()
|
||||
|
||||
if not existing_record:
|
||||
print(f"Record with ID {record_id} not found. Update operation aborted.")
|
||||
return
|
||||
|
||||
# Vraag de gebruiker om nieuwe waarden voor de andere velden
|
||||
new_timestamp = input("Enter new timestamp: ")
|
||||
new_gateway_receive_time = input("Enter new gateway_receive_time: ")
|
||||
new_device = input("Enter new device: ")
|
||||
new_value = input("Enter new value: ")
|
||||
|
||||
# Hier moet je de juiste kolomnamen aanpassen op basis van de structuur van je database
|
||||
update_query = """
|
||||
UPDATE goodgarden.battery_voltage_events
|
||||
SET timestamp = %s, gateway_receive_time = %s, device = %s, value = %s
|
||||
WHERE id = %s
|
||||
"""
|
||||
|
||||
# Voer de query uit
|
||||
print(f"Executing update query: {update_query}")
|
||||
print(f"Updating record with ID {record_id} to new values - timestamp: {new_timestamp}, gateway_receive_time: {new_gateway_receive_time}, device: {new_device}, value: {new_value}")
|
||||
|
||||
mycursor.execute(update_query, (new_timestamp, new_gateway_receive_time, new_device, new_value, record_id))
|
||||
|
||||
# Bevestig de wijzigingen
|
||||
mydb.commit()
|
||||
|
||||
print(f"Update executed. Rowcount: {mycursor.rowcount}")
|
||||
|
||||
except mysql.connector.Error as update_err:
|
||||
print(f"Error updating data: {update_err}")
|
||||
finally:
|
||||
# Zorg ervoor dat je altijd de cursor en de databaseverbinding sluit
|
||||
if 'mycursor' in locals() and mycursor is not None:
|
||||
mycursor.close()
|
||||
if 'mydb' in locals() and mydb.is_connected():
|
||||
mydb.close()
|
||||
|
||||
# Functie voor het verwijderen van gegevens uit de database
|
||||
def delete_data(record_id):
|
||||
mydb = database_connect()
|
||||
if mydb.is_connected():
|
||||
mycursor = mydb.cursor()
|
||||
|
||||
# Hier moet je de juiste kolomnamen aanpassen op basis van de structuur van je database
|
||||
delete_query = """
|
||||
DELETE FROM goodgarden.battery_voltage_events
|
||||
WHERE id = %s
|
||||
"""
|
||||
|
||||
# Voer de query uit
|
||||
mycursor.execute(delete_query, (record_id,))
|
||||
|
||||
# Bevestig de wijzigingen
|
||||
mydb.commit()
|
||||
|
||||
# Sluit cursor en verbinding
|
||||
mycursor.close()
|
||||
mydb.close()
|
||||
|
||||
print(f"Data with ID {record_id} deleted.")
|
||||
|
||||
# Functie voor het aanmaken van gegevens in de database op basis van batterijspanningsinformatie
|
||||
|
||||
if __name__ == "__main__":
|
||||
url = "https://garden.inajar.nl/api/battery_voltage_events/?format=json"
|
||||
access_token = "33bb3b42452306c58ecedc3c86cfae28ba22329c" # Vervang dit door je werkelijke toegangstoken
|
||||
|
||||
# Je kunt repeat_count wijzigen om te bepalen hoe vaak je de bewerking wilt herhalen
|
||||
repeat_count = 10
|
||||
|
||||
# Keuze voor de bewerking
|
||||
operation_choice = input("Choose operation (C for Create, R for Read, U for Update, D for Delete): ").upper()
|
||||
|
||||
if operation_choice == "C":
|
||||
# Maak gegevens aan
|
||||
create_data(url, access_token, repeat_count)
|
||||
elif operation_choice == "R":
|
||||
# Lees gegevens
|
||||
read_data(url, access_token, repeat_count)
|
||||
elif operation_choice == "U":
|
||||
# Update gegevens
|
||||
record_id = int(input("Enter record ID to update: "))
|
||||
# Call the update_data function without additional arguments
|
||||
update_data(record_id)
|
||||
elif operation_choice == "D":
|
||||
# Verwijder gegevens
|
||||
record_id = int(input("Enter record ID to delete: "))
|
||||
delete_data(record_id)
|
||||
else:
|
||||
print("Invalid operation choice. Please choose C, R, U, or D.")
|
||||
@@ -1,4 +1,4 @@
|
||||
import mysql.connector #** TYPE IN TERMINAL: "pip install mysql-connector-python"
|
||||
import mysql.connector
|
||||
from mysql.connector import Error
|
||||
|
||||
def database_connect():
|
||||
36
src/py/script/devices.py
Normal file
@@ -0,0 +1,36 @@
|
||||
import json
|
||||
|
||||
from paho.mqtt import subscribe
|
||||
|
||||
def on_message(client, userdata, message):
|
||||
payload_str = message.payload.decode("utf-8")
|
||||
data = json.loads(payload_str)
|
||||
|
||||
device_256 = None
|
||||
last_seen = None
|
||||
last_battery_voltage = None
|
||||
|
||||
device_322 = None
|
||||
last_seen = None
|
||||
last_battery_voltage = None
|
||||
|
||||
for key in data["results"]:
|
||||
if int(key["id"]) == 256:
|
||||
device_256 = int(key["id"])
|
||||
last_seen = int(key["last_seen"])
|
||||
last_battery_voltage = float(key["last_battery_voltage"])
|
||||
# print(f"{device_256}")
|
||||
print(f"Het device {device_256} is voor het laatst geien op: {last_seen} met de voltage als {last_battery_voltage}")
|
||||
|
||||
elif int(key["id"]) == 322:
|
||||
device_322 = int(key["id"])
|
||||
last_seen = int(key["last_seen"])
|
||||
last_battery_voltage = float(key["last_battery_voltage"])
|
||||
# print(f"{device_256}")
|
||||
print(f"Het device {device_322} is voor het laatst gezien op: {last_seen} met de voltage als {last_battery_voltage}")
|
||||
|
||||
print(f"\033[92mMessage received on topic\033[0m {message.topic}: {data}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
topic = "goodgarden/devices"
|
||||
subscribe.callback(on_message, topic)
|
||||
346
src/py/script/goodgarden.sql
Normal file
@@ -0,0 +1,346 @@
|
||||
-- phpMyAdmin SQL Dump
|
||||
-- version 5.2.1
|
||||
-- https://www.phpmyadmin.net/
|
||||
--
|
||||
-- Host: 127.0.0.1
|
||||
-- Gegenereerd op: 14 feb 2024 om 14:36
|
||||
-- Serverversie: 10.4.28-MariaDB
|
||||
-- PHP-versie: 8.2.4
|
||||
|
||||
DROP DATABASE IF EXISTS goodgarden;
|
||||
CREATE DATABASE goodgarden;
|
||||
|
||||
USE goodgarden;
|
||||
|
||||
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
|
||||
START TRANSACTION;
|
||||
SET time_zone = "+00:00";
|
||||
|
||||
|
||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
||||
/*!40101 SET NAMES utf8mb4 */;
|
||||
|
||||
--
|
||||
-- Database: `goodgarden`
|
||||
--
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabelstructuur voor tabel `battery_voltage_events`
|
||||
--
|
||||
|
||||
CREATE TABLE `battery_voltage_events` (
|
||||
`id` int(10) UNSIGNED NOT NULL,
|
||||
`timestamp` int(11) DEFAULT NULL,
|
||||
`gateway_receive_time` varchar(50) DEFAULT NULL,
|
||||
`device` int(11) DEFAULT NULL,
|
||||
`value` decimal(10,5) DEFAULT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
--
|
||||
-- Gegevens worden geëxporteerd voor tabel `battery_voltage_events`
|
||||
--
|
||||
|
||||
INSERT INTO `battery_voltage_events` (`id`, `timestamp`, `gateway_receive_time`, `device`, `value`) VALUES
|
||||
(1, 1707825721, '2024-02-13T12:02:01Z', 256, 4.09890),
|
||||
(2, 1707837460, '2024-02-13T15:17:40Z', 322, 4.10501),
|
||||
(3, 1707825721, '2024-02-13T12:02:01Z', 256, 4.09890),
|
||||
(4, 1707837460, '2024-02-13T15:17:40Z', 322, 4.10501),
|
||||
(5, 1707825721, '2024-02-13T12:02:01Z', 256, 4.09890),
|
||||
(6, 1707837460, '2024-02-13T15:17:40Z', 322, 4.10501),
|
||||
(7, 1707825721, '2024-02-13T12:02:01Z', 256, 4.09890),
|
||||
(8, 1707837460, '2024-02-13T15:17:40Z', 322, 4.10501),
|
||||
(9, 1707825721, '2024-02-13T12:02:01Z', 256, 4.09890),
|
||||
(10, 1707837460, '2024-02-13T15:17:40Z', 322, 4.10501);
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabelstructuur voor tabel `devices`
|
||||
--
|
||||
|
||||
CREATE TABLE `devices` (
|
||||
`id` int(10) UNSIGNED NOT NULL,
|
||||
`serial_number` varchar(255) DEFAULT NULL,
|
||||
`name` varchar(255) DEFAULT NULL,
|
||||
`label` varchar(255) DEFAULT NULL,
|
||||
`last_seen` int(11) DEFAULT NULL,
|
||||
`last_battery_voltage` float DEFAULT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
--
|
||||
-- Gegevens worden geëxporteerd voor tabel `devices`
|
||||
--
|
||||
|
||||
INSERT INTO `devices` (`id`, `serial_number`, `name`, `label`, `last_seen`, `last_battery_voltage`) VALUES
|
||||
(1, '0033889B1BAB1169', 'firefly2_0051', 'The Field', 1707765066, 4.09768),
|
||||
(2, '006FE1FC316ED7D8', 'firefly2_0111', 'The Field', 1707764966, 4.10745);
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabelstructuur voor tabel `fetch`
|
||||
--
|
||||
|
||||
CREATE TABLE `fetch` (
|
||||
`id` int(10) UNSIGNED NOT NULL,
|
||||
`timestamp` int(11) DEFAULT NULL,
|
||||
`gateway_receive_time` varchar(50) DEFAULT NULL,
|
||||
`device` int(11) DEFAULT NULL,
|
||||
`value` decimal(10,5) DEFAULT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
--
|
||||
-- Gegevens worden geëxporteerd voor tabel `fetch`
|
||||
--
|
||||
|
||||
INSERT INTO `fetch` (`id`, `timestamp`, `gateway_receive_time`, `device`, `value`) VALUES
|
||||
(70, 1707851215, '2024-02-13T19:06:55Z', 322, 0.00000),
|
||||
(71, 1707851215, '2024-02-13T19:06:55Z', 322, 1.52000),
|
||||
(72, 1707851215, '2024-02-13T19:06:55Z', 322, 12.06000),
|
||||
(73, 1707825721, '2024-02-13T12:02:01Z', 256, 4.09890),
|
||||
(74, 1707837460, '2024-02-13T15:17:40Z', 322, 4.10501),
|
||||
(75, 0, '', 0, 0.00000),
|
||||
(76, 0, '', 0, 0.00000),
|
||||
(77, 1707844638, '2024-02-13T17:17:18Z', 322, 0.00000),
|
||||
(78, 1707851099, '2024-02-13T19:04:59Z', 256, 0.00000),
|
||||
(79, 1707844638, '2024-02-13T17:17:18Z', 322, 71.08984),
|
||||
(80, 1707851099, '2024-02-13T19:04:59Z', 256, 66.72949),
|
||||
(81, 1707851215, '2024-02-13T19:06:55Z', 322, 0.00000),
|
||||
(82, 1707851215, '2024-02-13T19:06:55Z', 322, 1.52000),
|
||||
(83, 1707851215, '2024-02-13T19:06:55Z', 322, 12.06000),
|
||||
(84, 0, '', 0, 0.00000),
|
||||
(85, 0, '', 0, 0.00000),
|
||||
(86, 1707844638, '2024-02-13T17:17:18Z', 322, 0.00000),
|
||||
(87, 1707851099, '2024-02-13T19:04:59Z', 256, 0.00000),
|
||||
(88, 1707844638, '2024-02-13T17:17:18Z', 322, 71.08984),
|
||||
(89, 1707851099, '2024-02-13T19:04:59Z', 256, 66.72949),
|
||||
(90, 1707825721, '2024-02-13T12:02:01Z', 256, 4.09890),
|
||||
(91, 1707837460, '2024-02-13T15:17:40Z', 322, 4.10501),
|
||||
(92, 0, '', 0, 0.00000),
|
||||
(93, 0, '', 0, 0.00000),
|
||||
(94, 1707844638, '2024-02-13T17:17:18Z', 322, 0.00000),
|
||||
(95, 1707851099, '2024-02-13T19:04:59Z', 256, 0.00000),
|
||||
(96, 1707844638, '2024-02-13T17:17:18Z', 322, 71.08984),
|
||||
(97, 1707851099, '2024-02-13T19:04:59Z', 256, 66.72949);
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabelstructuur voor tabel `par_events`
|
||||
--
|
||||
|
||||
CREATE TABLE `par_events` (
|
||||
`id` int(10) UNSIGNED NOT NULL,
|
||||
`timestamp` int(11) DEFAULT NULL,
|
||||
`gateway_receive_time` varchar(50) DEFAULT NULL,
|
||||
`device` int(11) DEFAULT NULL,
|
||||
`value` decimal(10,5) DEFAULT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
--
|
||||
-- Gegevens worden geëxporteerd voor tabel `par_events`
|
||||
--
|
||||
|
||||
INSERT INTO `par_events` (`id`, `timestamp`, `gateway_receive_time`, `device`, `value`) VALUES
|
||||
(1, 1707844638, '2024-02-13T17:17:18Z', 322, 0.00000),
|
||||
(2, 1707851099, '2024-02-13T19:04:59Z', 256, 0.00000);
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabelstructuur voor tabel `relative_humidity_events`
|
||||
--
|
||||
|
||||
CREATE TABLE `relative_humidity_events` (
|
||||
`id` int(10) UNSIGNED NOT NULL,
|
||||
`timestamp` int(11) DEFAULT NULL,
|
||||
`gateway_receive_time` varchar(50) DEFAULT NULL,
|
||||
`device` int(11) DEFAULT NULL,
|
||||
`value` decimal(10,5) DEFAULT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
--
|
||||
-- Gegevens worden geëxporteerd voor tabel `relative_humidity_events`
|
||||
--
|
||||
|
||||
INSERT INTO `relative_humidity_events` (`id`, `timestamp`, `gateway_receive_time`, `device`, `value`) VALUES
|
||||
(3, 1707844638, '2024-02-13T17:17:18Z', 322, 71.08984),
|
||||
(4, 1707851099, '2024-02-13T19:04:59Z', 256, 66.72949),
|
||||
(5, 1707844638, '2024-02-13T17:17:18Z', 322, 71.08984),
|
||||
(6, 1707851099, '2024-02-13T19:04:59Z', 256, 66.72949);
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabelstructuur voor tabel `soil_electric_conductivity_events`
|
||||
--
|
||||
|
||||
CREATE TABLE `soil_electric_conductivity_events` (
|
||||
`id` int(10) UNSIGNED NOT NULL,
|
||||
`timestamp` int(11) DEFAULT NULL,
|
||||
`gateway_receive_time` varchar(50) DEFAULT NULL,
|
||||
`device` int(11) DEFAULT NULL,
|
||||
`value` decimal(10,5) DEFAULT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
--
|
||||
-- Gegevens worden geëxporteerd voor tabel `soil_electric_conductivity_events`
|
||||
--
|
||||
|
||||
INSERT INTO `soil_electric_conductivity_events` (`id`, `timestamp`, `gateway_receive_time`, `device`, `value`) VALUES
|
||||
(3, 1707851215, '2024-02-13T19:06:55Z', 322, 0.00000);
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabelstructuur voor tabel `soil_relative_permittivity_events`
|
||||
--
|
||||
|
||||
CREATE TABLE `soil_relative_permittivity_events` (
|
||||
`id` int(10) UNSIGNED NOT NULL,
|
||||
`timestamp` int(11) DEFAULT NULL,
|
||||
`gateway_receive_time` varchar(50) DEFAULT NULL,
|
||||
`device` int(11) DEFAULT NULL,
|
||||
`value` decimal(10,5) DEFAULT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
--
|
||||
-- Gegevens worden geëxporteerd voor tabel `soil_relative_permittivity_events`
|
||||
--
|
||||
|
||||
INSERT INTO `soil_relative_permittivity_events` (`id`, `timestamp`, `gateway_receive_time`, `device`, `value`) VALUES
|
||||
(3, 1707851215, '2024-02-13T19:06:55Z', 322, 1.52000);
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Tabelstructuur voor tabel `soil_temperature_events`
|
||||
--
|
||||
|
||||
CREATE TABLE `soil_temperature_events` (
|
||||
`id` int(10) NOT NULL,
|
||||
`timestamp` int(11) DEFAULT NULL,
|
||||
`gateway_receive_time` varchar(50) DEFAULT NULL,
|
||||
`device` int(11) DEFAULT NULL,
|
||||
`value` decimal(10,5) DEFAULT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
--
|
||||
-- Gegevens worden geëxporteerd voor tabel `soil_temperature_events`
|
||||
--
|
||||
|
||||
INSERT INTO `soil_temperature_events` (`id`, `timestamp`, `gateway_receive_time`, `device`, `value`) VALUES
|
||||
(3, 1707851215, '2024-02-13T19:06:55Z', 322, 12.06000);
|
||||
|
||||
--
|
||||
-- Indexen voor geëxporteerde tabellen
|
||||
--
|
||||
|
||||
--
|
||||
-- Indexen voor tabel `battery_voltage_events`
|
||||
--
|
||||
ALTER TABLE `battery_voltage_events`
|
||||
ADD PRIMARY KEY (`id`);
|
||||
|
||||
--
|
||||
-- Indexen voor tabel `devices`
|
||||
--
|
||||
ALTER TABLE `devices`
|
||||
ADD PRIMARY KEY (`id`);
|
||||
|
||||
--
|
||||
-- Indexen voor tabel `fetch`
|
||||
--
|
||||
ALTER TABLE `fetch`
|
||||
ADD PRIMARY KEY (`id`);
|
||||
|
||||
--
|
||||
-- Indexen voor tabel `par_events`
|
||||
--
|
||||
ALTER TABLE `par_events`
|
||||
ADD PRIMARY KEY (`id`);
|
||||
|
||||
--
|
||||
-- Indexen voor tabel `relative_humidity_events`
|
||||
--
|
||||
ALTER TABLE `relative_humidity_events`
|
||||
ADD PRIMARY KEY (`id`);
|
||||
|
||||
--
|
||||
-- Indexen voor tabel `soil_electric_conductivity_events`
|
||||
--
|
||||
ALTER TABLE `soil_electric_conductivity_events`
|
||||
ADD PRIMARY KEY (`id`);
|
||||
|
||||
--
|
||||
-- Indexen voor tabel `soil_relative_permittivity_events`
|
||||
--
|
||||
ALTER TABLE `soil_relative_permittivity_events`
|
||||
ADD PRIMARY KEY (`id`);
|
||||
|
||||
--
|
||||
-- Indexen voor tabel `soil_temperature_events`
|
||||
--
|
||||
ALTER TABLE `soil_temperature_events`
|
||||
ADD PRIMARY KEY (`id`);
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT voor geëxporteerde tabellen
|
||||
--
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT voor een tabel `battery_voltage_events`
|
||||
--
|
||||
ALTER TABLE `battery_voltage_events`
|
||||
MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=11;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT voor een tabel `devices`
|
||||
--
|
||||
ALTER TABLE `devices`
|
||||
MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT voor een tabel `fetch`
|
||||
--
|
||||
ALTER TABLE `fetch`
|
||||
MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=98;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT voor een tabel `par_events`
|
||||
--
|
||||
ALTER TABLE `par_events`
|
||||
MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT voor een tabel `relative_humidity_events`
|
||||
--
|
||||
ALTER TABLE `relative_humidity_events`
|
||||
MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=7;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT voor een tabel `soil_electric_conductivity_events`
|
||||
--
|
||||
ALTER TABLE `soil_electric_conductivity_events`
|
||||
MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT voor een tabel `soil_relative_permittivity_events`
|
||||
--
|
||||
ALTER TABLE `soil_relative_permittivity_events`
|
||||
MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4;
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT voor een tabel `soil_temperature_events`
|
||||
--
|
||||
ALTER TABLE `soil_temperature_events`
|
||||
MODIFY `id` int(10) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4;
|
||||
COMMIT;
|
||||
|
||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
||||
25
src/py/script/par_events.py
Normal file
@@ -0,0 +1,25 @@
|
||||
import json
|
||||
|
||||
from paho.mqtt import subscribe
|
||||
|
||||
def on_message(client, userdata, message):
|
||||
payload_str = message.payload.decode("utf-8")
|
||||
data = json.loads(payload_str)
|
||||
|
||||
device_322_value = None
|
||||
device_256_value = None
|
||||
|
||||
for key in data["results"]:
|
||||
if key["device"] == 322:
|
||||
device_322_value = key["value"]
|
||||
elif key["device"] == 256:
|
||||
device_256_value = key["value"]
|
||||
|
||||
print(f"Device 322 value: {device_322_value}")
|
||||
print(f"Device 256 value: {device_256_value}")
|
||||
|
||||
print(f"Message received on topic {message.topic}: {data}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
topic = "goodgarden/par_events"
|
||||
subscribe.callback(on_message, topic)
|
||||
49
src/py/script/planten.py
Normal file
@@ -0,0 +1,49 @@
|
||||
import json
|
||||
import mysql.connector
|
||||
import os
|
||||
|
||||
# Function to make a connection to the database
|
||||
def database_connect():
|
||||
return mysql.connector.connect(
|
||||
host="localhost",
|
||||
user="root",
|
||||
password="",
|
||||
database="goodgarden"
|
||||
)
|
||||
|
||||
# Function to get the absolute path of the current directory
|
||||
def get_current_directory():
|
||||
return os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
def fetch_plant_and_write_to_json():
|
||||
# Establish a database connection
|
||||
connection = database_connect()
|
||||
|
||||
try:
|
||||
cursor = connection.cursor(dictionary=True) # To fetch rows as dictionaries
|
||||
# Execute the query to fetch data
|
||||
cursor.execute("SELECT id, plant_naam, plantensoort, plant_geteelt FROM planten")
|
||||
# Fetch all rows
|
||||
plants = cursor.fetchall()
|
||||
|
||||
# Get the absolute path of the current directory
|
||||
current_directory = get_current_directory()
|
||||
# Construct the absolute path for the JSON file
|
||||
json_file_path = os.path.join(current_directory, 'plants.json')
|
||||
|
||||
# Write fetched data to JSON file
|
||||
with open(json_file_path, 'w') as json_file:
|
||||
json.dump(plants, json_file, indent=4)
|
||||
|
||||
except mysql.connector.Error as error:
|
||||
print("Error fetching data from MySQL table:", error)
|
||||
|
||||
finally:
|
||||
# Close cursor and connection
|
||||
if 'cursor' in locals():
|
||||
cursor.close()
|
||||
if connection.is_connected():
|
||||
connection.close()
|
||||
|
||||
# Call the function to fetch data and write to JSON
|
||||
fetch_plant_and_write_to_json()
|
||||
32
src/py/script/plants.json
Normal file
@@ -0,0 +1,32 @@
|
||||
[
|
||||
{
|
||||
"id": 47,
|
||||
"plant_naam": "Tomaten",
|
||||
"plantensoort": "Groente",
|
||||
"plant_geteelt": 1
|
||||
},
|
||||
{
|
||||
"id": 49,
|
||||
"plant_naam": "Komkommer",
|
||||
"plantensoort": "Groente",
|
||||
"plant_geteelt": 1
|
||||
},
|
||||
{
|
||||
"id": 50,
|
||||
"plant_naam": "Appel",
|
||||
"plantensoort": "Fruit",
|
||||
"plant_geteelt": 1
|
||||
},
|
||||
{
|
||||
"id": 51,
|
||||
"plant_naam": "Sla",
|
||||
"plantensoort": "Groente",
|
||||
"plant_geteelt": 1
|
||||
},
|
||||
{
|
||||
"id": 52,
|
||||
"plant_naam": "Wietplant",
|
||||
"plantensoort": "Onkruid",
|
||||
"plant_geteelt": 0
|
||||
}
|
||||
]
|
||||
13
src/py/script/relative_humidity_events.py
Normal file
@@ -0,0 +1,13 @@
|
||||
import json
|
||||
|
||||
from paho.mqtt import subscribe
|
||||
|
||||
def on_message(client, userdata, message):
|
||||
payload_str = message.payload.decode("utf-8")
|
||||
data = json.loads(payload_str)
|
||||
|
||||
print(f"Message received on topic {message.topic}: {data}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
topic = "goodgarden/relative_humidity"
|
||||
subscribe.callback(on_message, topic)
|
||||
218
src/py/script/samenvoegen_databases.py
Normal file
@@ -0,0 +1,218 @@
|
||||
import requests
|
||||
import time
|
||||
|
||||
from db_connect import database_connect
|
||||
|
||||
##########################* DEVICES #######################
|
||||
|
||||
def load_data(data):
|
||||
mydb = database_connect()
|
||||
if mydb.is_connected():
|
||||
mycursor = mydb.cursor()
|
||||
|
||||
insert_query = """
|
||||
INSERT INTO goodgarden.devices (serial_number, name, label, last_seen, last_battery_voltage)
|
||||
VALUES (%s, %s, %s, %s, %s )
|
||||
"""
|
||||
for record in data['results']:
|
||||
serial_number = record.get('serial_number', '')
|
||||
name = record.get('name', '')
|
||||
label = record.get('label', '')
|
||||
last_seen = record.get('last_seen', '')
|
||||
last_battery_voltage = record.get('last_battery_voltage', '')
|
||||
|
||||
print(f"Inserting data: serial_number={serial_number}, name={name}, label={label}, last_seen={last_seen}, last_battery_voltage={last_battery_voltage}")
|
||||
|
||||
mycursor.execute(insert_query, (serial_number, name, label, last_seen, last_battery_voltage))
|
||||
|
||||
mydb.commit()
|
||||
|
||||
mycursor.close()
|
||||
mydb.close()
|
||||
|
||||
print("Data inserted into the database.")
|
||||
|
||||
############################### EINDE ########################
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
##########################* PAR_EVENTS #######################
|
||||
|
||||
def load_data(data):
|
||||
mydb = database_connect()
|
||||
if mydb.is_connected():
|
||||
mycursor = mydb.cursor()
|
||||
|
||||
# Here you need to adjust the correct column names and data formats based on the API response
|
||||
insert_query = """
|
||||
INSERT INTO goodgarden.par_events (timestamp, gateway_receive_time, device, value)
|
||||
VALUES (%s, %s, %s, %s)
|
||||
"""
|
||||
for record in data['results']:
|
||||
timestamp = record.get('timestamp', '')
|
||||
gateway_receive_time = record.get('gateway_receive_time', '')
|
||||
device = record.get('device', '')
|
||||
value = record.get('value', '')
|
||||
|
||||
print(f"Inserting data: timestamp={timestamp}, gateway_receive_time={gateway_receive_time}, device={device}, value={value}")
|
||||
|
||||
# Execute the query
|
||||
mycursor.execute(insert_query, (timestamp, gateway_receive_time, device, value))
|
||||
|
||||
# Commit the changes
|
||||
mydb.commit()
|
||||
|
||||
# Close cursor and connection
|
||||
mycursor.close()
|
||||
mydb.close()
|
||||
|
||||
print("Data inserted into the database.")
|
||||
|
||||
############################### EINDE ########################
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
##########################* RELATIVE_HUMIDITY_EVENTS #######################
|
||||
|
||||
def load_data(data):
|
||||
mydb = database_connect()
|
||||
if mydb.is_connected():
|
||||
mycursor = mydb.cursor()
|
||||
|
||||
# Here you need to adjust the correct column names and data formats based on the API response
|
||||
insert_query = """
|
||||
INSERT INTO goodgarden.relative_humidity_events (timestamp, gateway_receive_time, device, value)
|
||||
VALUES (%s, %s, %s, %s)
|
||||
"""
|
||||
for record in data['results']:
|
||||
timestamp = record.get('timestamp', '')
|
||||
gateway_receive_time = record.get('gateway_receive_time', '')
|
||||
device = record.get('device', '')
|
||||
value = record.get('value', '')
|
||||
|
||||
print(f"Inserting data: timestamp={timestamp}, gateway_receive_time={gateway_receive_time}, device={device}, value={value}")
|
||||
|
||||
# Execute the query
|
||||
mycursor.execute(insert_query, (timestamp, gateway_receive_time, device, value))
|
||||
|
||||
# Commit the changes
|
||||
mydb.commit()
|
||||
|
||||
# Close cursor and connection
|
||||
mycursor.close()
|
||||
mydb.close()
|
||||
|
||||
print("Data inserted into the database.")
|
||||
|
||||
############################### EINDE ########################
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
##########################* SOIL_ELECTRIC_CONDUCTIVITY_EVENTS #######################
|
||||
|
||||
def load_data(data):
|
||||
mydb = database_connect()
|
||||
if mydb.is_connected():
|
||||
mycursor = mydb.cursor()
|
||||
|
||||
# Here you need to adjust the correct column names and data formats based on the API response
|
||||
insert_query = """
|
||||
INSERT INTO goodgarden.soil_electric_conductivity_events (timestamp, gateway_receive_time, device, value)
|
||||
VALUES (%s, %s, %s, %s)
|
||||
"""
|
||||
for record in data['results']:
|
||||
timestamp = record.get('timestamp', '')
|
||||
gateway_receive_time = record.get('gateway_receive_time', '')
|
||||
device = record.get('device', '')
|
||||
value = record.get('value', '')
|
||||
|
||||
print(f"Inserting data: timestamp={timestamp}, gateway_receive_time={gateway_receive_time}, device={device}, value={value}")
|
||||
|
||||
# Execute the query
|
||||
mycursor.execute(insert_query, (timestamp, gateway_receive_time, device, value))
|
||||
|
||||
# Commit the changes
|
||||
mydb.commit()
|
||||
|
||||
# Close cursor and connection
|
||||
mycursor.close()
|
||||
mydb.close()
|
||||
|
||||
print("Data inserted into the database.")
|
||||
|
||||
############################### EINDE ########################
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
##########################* SOIL_TEMPERATURE_EVENTS #######################
|
||||
|
||||
def load_data(data):
|
||||
mydb = database_connect()
|
||||
if mydb.is_connected():
|
||||
mycursor = mydb.cursor()
|
||||
|
||||
# Here you need to adjust the correct column names and data formats based on the API response
|
||||
insert_query = """
|
||||
INSERT INTO goodgarden.soil_temperature_events (timestamp, gateway_receive_time, device, value)
|
||||
VALUES (%s, %s, %s, %s)
|
||||
"""
|
||||
for record in data['results']:
|
||||
timestamp = record.get('timestamp', '')
|
||||
gateway_receive_time = record.get('gateway_receive_time', '')
|
||||
device = record.get('device', '')
|
||||
value = record.get('value', '')
|
||||
|
||||
print(f"Inserting data: timestamp={timestamp}, gateway_receive_time={gateway_receive_time}, device={device}, value={value}")
|
||||
|
||||
# Execute the query
|
||||
mycursor.execute(insert_query, (timestamp, gateway_receive_time, device, value))
|
||||
|
||||
# Commit the changes
|
||||
mydb.commit()
|
||||
|
||||
# Close cursor and connection
|
||||
mycursor.close()
|
||||
mydb.close()
|
||||
|
||||
print("Data inserted into the database.")
|
||||
|
||||
############################### EINDE ########################
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
# #
|
||||
##########################* SOIL_TEMPERATURE_EVENTS #######################
|
||||
|
||||
def load_data(data):
|
||||
mydb = database_connect()
|
||||
if mydb.is_connected():
|
||||
mycursor = mydb.cursor()
|
||||
|
||||
# Here you need to adjust the correct column names and data formats based on the API response
|
||||
insert_query = """
|
||||
INSERT INTO goodgarden.soil_temperature_events (timestamp, gateway_receive_time, device, value)
|
||||
VALUES (%s, %s, %s, %s)
|
||||
"""
|
||||
for record in data['results']:
|
||||
timestamp = record.get('timestamp', '')
|
||||
gateway_receive_time = record.get('gateway_receive_time', '')
|
||||
device = record.get('device', '')
|
||||
value = record.get('value', '')
|
||||
|
||||
print(f"Inserting data: timestamp={timestamp}, gateway_receive_time={gateway_receive_time}, device={device}, value={value}")
|
||||
|
||||
# Execute the query
|
||||
mycursor.execute(insert_query, (timestamp, gateway_receive_time, device, value))
|
||||
|
||||
# Commit the changes
|
||||
mydb.commit()
|
||||
|
||||
# Close cursor and connection
|
||||
mycursor.close()
|
||||
mydb.close()
|
||||
|
||||
print("Data inserted into the database.")
|
||||
74
src/py/script/servermqtt.py
Normal file
@@ -0,0 +1,74 @@
|
||||
import os
|
||||
import time
|
||||
import requests
|
||||
import paho.mqtt.client as mqtt
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv()
|
||||
|
||||
API_URL = os.getenv("API_URL")
|
||||
MQTT_HOST = os.getenv("MQTT_HOST")
|
||||
MQTT_PORT = int(os.getenv("MQTT_PORT", 1883))
|
||||
|
||||
def get_data_from_api(request):
|
||||
links = {
|
||||
'battery': '/battery_voltage_events/',
|
||||
'devices': '/devices/',
|
||||
'parEvents': '/par_events/',
|
||||
'humidity': '/relative_humidity_events/',
|
||||
'soilConductifity': '/soil_electric_conductivity_events/',
|
||||
'soilPermittivity' : '/soil_relative_permittivity_events/',
|
||||
'soilTemperature': '/soil_temperature_events/'
|
||||
}
|
||||
headers = {
|
||||
'accept': 'application/json',
|
||||
'Authorization': f'Token {os.getenv("API_TOKEN")}'
|
||||
}
|
||||
url = API_URL + links[request]
|
||||
try:
|
||||
response = requests.get(url, headers=headers)
|
||||
response.raise_for_status()
|
||||
except requests.exceptions.HTTPError as errh:
|
||||
print ("HTTP Error:",errh)
|
||||
return None
|
||||
except requests.exceptions.ConnectionError as errc:
|
||||
print ("Error Connecting:",errc)
|
||||
return None
|
||||
except requests.exceptions.Timeout as errt:
|
||||
print ("Timeout Error:",errt)
|
||||
return None
|
||||
except requests.exceptions.RequestException as err:
|
||||
print ("Something went wrong",err)
|
||||
return None
|
||||
|
||||
data = response.json()
|
||||
return data['results']
|
||||
|
||||
def publish_to_mqtt(topic, message):
|
||||
client = mqtt.Client()
|
||||
client.connect(MQTT_HOST, MQTT_PORT, 60)
|
||||
try:
|
||||
client.publish(topic, message)
|
||||
except mqtt.MQTTException as e:
|
||||
print(f"Failed to publish message: {e}")
|
||||
finally:
|
||||
client.disconnect()
|
||||
|
||||
def process_results(link, results):
|
||||
for result in results:
|
||||
if 'timestamp' in result and 'gateway_receive_time' in result and 'device' in result and 'value' in result:
|
||||
message = f"Timestamp: {result['timestamp']}, Gateway Receive Time: {result['gateway_receive_time']}, Device: {result['device']}, Value: {result['value']}"
|
||||
print(message)
|
||||
publish_to_mqtt(link, message)
|
||||
|
||||
def main():
|
||||
links = ['battery', 'devices', 'parEvents', 'humidity', 'soilConductifity', 'soilPermittivity', 'soilTemperature']
|
||||
while True:
|
||||
for link in links:
|
||||
results = get_data_from_api(link)
|
||||
if results is not None:
|
||||
process_results(link, results)
|
||||
time.sleep(5)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
13
src/py/script/soil_electric_conductivity_events.py
Normal file
@@ -0,0 +1,13 @@
|
||||
import json
|
||||
|
||||
from paho.mqtt import subscribe
|
||||
|
||||
def on_message(client, userdata, message):
|
||||
payload_str = message.payload.decode("utf-8")
|
||||
data = json.loads(payload_str)
|
||||
|
||||
print(f"Message received on topic {message.topic}: {data}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
topic = "goodgarden/soil_electric_conductivity"
|
||||
subscribe.callback(on_message, topic)
|
||||
13
src/py/script/soil_relative_permittivity_events.py
Normal file
@@ -0,0 +1,13 @@
|
||||
import json
|
||||
|
||||
from paho.mqtt import subscribe
|
||||
|
||||
def on_message(client, userdata, message):
|
||||
payload_str = message.payload.decode("utf-8")
|
||||
data = json.loads(payload_str)
|
||||
|
||||
print(f"Message received on topic {message.topic}: {data}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
topic = "goodgarden/soil_relative_permittivity"
|
||||
subscribe.callback(on_message, topic)
|
||||
13
src/py/script/soil_temperature_events.py
Normal file
@@ -0,0 +1,13 @@
|
||||
import json
|
||||
|
||||
from paho.mqtt import subscribe
|
||||
|
||||
def on_message(client, userdata, message):
|
||||
payload_str = message.payload.decode("utf-8")
|
||||
data = json.loads(payload_str)
|
||||
|
||||
print(f"Message received on topic {message.topic}: {data}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
topic = "goodgarden/soil_temperature"
|
||||
subscribe.callback(on_message, topic)
|
||||
406
src/py/static/css/style.css
Normal file
@@ -0,0 +1,406 @@
|
||||
@import url("https://fonts.googleapis.com/css2?family=Akaya+Kanadaka&display=swap");
|
||||
@import url("https://fonts.googleapis.com/css2?family=Afacad:ital,wght@0,400..700;1,400..700&display=swap");
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5 {
|
||||
font-family: "Akaya Kanadaka", system-ui;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
p,
|
||||
td {
|
||||
font-family: "Afacad", sans-serif;
|
||||
color: black;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
body {
|
||||
background: linear-gradient(rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0.5)), url("../images/achtergrond.png");
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
font-family: "Afacad", sans-serif;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
}
|
||||
body .mainContainer {
|
||||
width: 85vw;
|
||||
height: 38rem;
|
||||
background-color: rgba(255, 255, 255, 0.85);
|
||||
border-radius: 40px;
|
||||
padding: 2rem;
|
||||
}
|
||||
body .mainContainer .goodgarden-logo {
|
||||
position: absolute;
|
||||
width: 10vw;
|
||||
left: 50%;
|
||||
top: 4.1rem;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
body .mainContainer .informatie-kas-main-container {
|
||||
display: grid;
|
||||
grid-template-columns: 5fr 7fr;
|
||||
}
|
||||
body .mainContainer .mainBorder {
|
||||
padding: 1.25rem 1.5rem;
|
||||
padding: 1rem 0;
|
||||
height: 35rem;
|
||||
border: solid 5px rgb(171, 211, 174);
|
||||
border-radius: 40px;
|
||||
}
|
||||
body .mainContainer .mainBorder .pagina-titel {
|
||||
font-size: 2rem;
|
||||
margin-left: 1.5rem;
|
||||
}
|
||||
body .mainContainer .mainBorder #sectie-1 {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
padding: 0 2.5rem 0 1rem;
|
||||
position: relative;
|
||||
}
|
||||
body .mainContainer .mainBorder #sectie-1 h1 {
|
||||
background-color: green;
|
||||
}
|
||||
body .mainContainer .mainBorder #sectie-1 .parent-algemeen-overzicht {
|
||||
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.5);
|
||||
border-radius: 40px;
|
||||
padding: 1rem;
|
||||
margin-top: 1rem;
|
||||
background-color: white;
|
||||
}
|
||||
body .mainContainer .mainBorder #sectie-1 .parent-algemeen-overzicht .algemeen-overzicht {
|
||||
border: solid 2px rgb(171, 211, 174);
|
||||
border-radius: 35px;
|
||||
font-size: 1.25rem;
|
||||
padding: 0.5rem 1rem;
|
||||
}
|
||||
body .mainContainer .mainBorder #sectie-1 .parent-algemeen-overzicht .algemeen-overzicht .table-informatie-kas {
|
||||
width: 100%;
|
||||
}
|
||||
body .mainContainer .mainBorder #sectie-1 .parent-algemeen-overzicht .algemeen-overzicht .table-informatie-kas .tr-informatie-kas {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
text-align: left;
|
||||
}
|
||||
body .mainContainer .mainBorder #sectie-1 .grafiek {
|
||||
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.5);
|
||||
border-radius: 40px;
|
||||
padding: 1rem;
|
||||
position: relative;
|
||||
background-color: white;
|
||||
}
|
||||
body .mainContainer .mainBorder #sectie-1 .grafiek .grafiek-innerbox {
|
||||
border: solid 2px rgb(171, 211, 174);
|
||||
border-radius: 35px;
|
||||
font-size: 1.25rem;
|
||||
padding: 0 1rem 2.5rem;
|
||||
height: 225px;
|
||||
position: relative;
|
||||
}
|
||||
body .mainContainer .mainBorder #sectie-1 .grafiek .grafiek-innerbox h2 {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
body .mainContainer .mainBorder #sectie-1 .grafiek .grafiek-innerbox canvas {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
body .mainContainer .mainBorder .content {
|
||||
display: grid;
|
||||
grid-template-columns: 3fr 1fr 3fr;
|
||||
height: 100%;
|
||||
}
|
||||
body .mainContainer .mainBorder .content .kant-links {
|
||||
grid-column: 1;
|
||||
}
|
||||
body .mainContainer .mainBorder .content .kant-links #planten {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
body .mainContainer .mainBorder .content .kant-links #planten td article {
|
||||
height: 7rem;
|
||||
width: 10rem;
|
||||
padding: 0.6rem;
|
||||
margin: 0.1rem;
|
||||
margin-left: 2rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border: solid 3px rgb(171, 211, 174);
|
||||
border-radius: 40px;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
body .mainContainer .mainBorder .content .kant-links #planten td article #toevoegen {
|
||||
height: 5rem;
|
||||
width: 5rem;
|
||||
}
|
||||
body .mainContainer .mainBorder .content .kant-links #planten td article h2 {
|
||||
color: gray;
|
||||
}
|
||||
body .mainContainer .mainBorder .content .kant-links #planten td article:hover {
|
||||
background-color: lightgray;
|
||||
}
|
||||
body .mainContainer .mainBorder .content .kant-rechts {
|
||||
grid-column: 3;
|
||||
}
|
||||
body .mainContainer .mainBorder .content .kant-rechts #metingen {
|
||||
border: solid 3px rgb(171, 211, 174);
|
||||
border-radius: 40px;
|
||||
}
|
||||
body .mainContainer .mainBorder .content .kant-rechts #metingen #main-waardes {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 0.5rem;
|
||||
padding-bottom: 0;
|
||||
width: 100%;
|
||||
}
|
||||
body .mainContainer .mainBorder .content .kant-rechts #metingen #main-waardes table {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
}
|
||||
body .mainContainer .mainBorder .grid-column-2 {
|
||||
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.5);
|
||||
border-radius: 40px;
|
||||
padding: 1rem;
|
||||
margin: 3.25rem 1rem 1.25rem 1rem;
|
||||
background-color: white;
|
||||
}
|
||||
body .mainContainer .mainBorder .grid-column-2 .grid-2-child {
|
||||
border: solid 2px rgb(171, 211, 174);
|
||||
border-radius: 35px;
|
||||
height: 100%;
|
||||
}
|
||||
body .mainContainer .mainBorder .grid-column-2 .grid-2-child .parent-table {
|
||||
padding: 1.5rem 2rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
gap: 2.5rem;
|
||||
justify-content: space-around;
|
||||
height: 90%;
|
||||
}
|
||||
body .mainContainer .mainBorder .grid-column-2 .grid-2-child .parent-table table tr td {
|
||||
font-size: 1.05rem;
|
||||
}
|
||||
body .mainContainer .mainBorder .grid-column-2 .grid-2-child .parent-table .kas-table-1 tr td {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
body .mainContainer .mainBorder .grid-column-2 .grid-2-child .parent-table .kas-table-2 {
|
||||
position: relative;
|
||||
}
|
||||
body .mainContainer .mainBorder .grid-column-2 .grid-2-child .parent-table .kas-table-2::after, body .mainContainer .mainBorder .grid-column-2 .grid-2-child .parent-table .kas-table-2::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 1px;
|
||||
width: 90%;
|
||||
background: black;
|
||||
}
|
||||
body .mainContainer .mainBorder .grid-column-2 .grid-2-child .parent-table .kas-table-2::after {
|
||||
bottom: -20px;
|
||||
}
|
||||
body .mainContainer .mainBorder .grid-column-2 .grid-2-child .parent-table .kas-table-2::before {
|
||||
top: -20px;
|
||||
}
|
||||
|
||||
.divider {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
border: solid 1px rgb(171, 211, 174);
|
||||
border-radius: 5px;
|
||||
width: 80%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.modal {
|
||||
display: none;
|
||||
position: fixed;
|
||||
z-index: 999;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
background: white;
|
||||
padding: 1.25rem;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
width: 30vw;
|
||||
height: auto;
|
||||
border: solid 2px #abd3ae;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.modal .close {
|
||||
color: #aaa;
|
||||
float: right;
|
||||
font-size: 1.75rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.modal .close:hover,
|
||||
.modal .close:active {
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#myModal select,
|
||||
#myModal input {
|
||||
width: calc(100% - 20px);
|
||||
padding: 10px;
|
||||
margin-bottom: 15px;
|
||||
border: 2px solid #abd3ae;
|
||||
border-radius: 5px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#myModal .knop {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
#myModal button {
|
||||
width: 48%;
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
#myModal .knop-container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
#myModal .knop-container input,
|
||||
#myModal .knop-container button {
|
||||
flex: 1;
|
||||
margin: 0 5px;
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#myModal input[type=text],
|
||||
#myModal select {
|
||||
border: 2px solid #abd3ae;
|
||||
padding: 10px;
|
||||
border-radius: 17px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#myModal input[type=submit],
|
||||
#myModal button {
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 15px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#myModal input[type=submit] {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
#myModal button {
|
||||
background-color: white;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.toevoeging {
|
||||
background: linear-gradient(45deg, #abd3ae, #2ecc71);
|
||||
}
|
||||
|
||||
.annulatie-knop {
|
||||
background: linear-gradient(45deg, #ffcc00, #ff6600);
|
||||
}
|
||||
|
||||
#myModal button:hover {
|
||||
background: linear-gradient(45deg, #abd3ae, #fff);
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.modal .close {
|
||||
color: #aaa;
|
||||
float: right;
|
||||
font-size: 1.75rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.modal .close:hover,
|
||||
.modal .close:active {
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.switch-container {
|
||||
display: flex;
|
||||
align-items: end;
|
||||
}
|
||||
|
||||
.switch {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 60px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.switch input {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.slider {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: #ccc;
|
||||
border-radius: 34px;
|
||||
transition: 0.4s;
|
||||
}
|
||||
|
||||
.slider:before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
height: 26px;
|
||||
width: 26px;
|
||||
left: 4px;
|
||||
bottom: 4px;
|
||||
background-color: white;
|
||||
border-radius: 50%;
|
||||
transition: 0.4s;
|
||||
}
|
||||
|
||||
input:checked + .slider {
|
||||
background-color: #2ecc71;
|
||||
}
|
||||
|
||||
input:checked + .slider:before {
|
||||
transform: translateX(26px);
|
||||
}
|
||||
|
||||
.rechterkant {
|
||||
display: flex;
|
||||
justify-content: end;
|
||||
}
|
||||
|
||||
.plant-container,
|
||||
#modalButton {
|
||||
background-color: white;
|
||||
}/*# sourceMappingURL=style.css.map */
|
||||
1
src/py/static/css/style.css.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["style.scss","style.css"],"names":[],"mappings":"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","file":"style.css"}
|
||||
534
src/py/static/css/style.scss
Normal file
@@ -0,0 +1,534 @@
|
||||
$primary-color: rgb(171, 211, 174);
|
||||
$secondary-color: rgb(143, 188, 143);
|
||||
|
||||
@import url("https://fonts.googleapis.com/css2?family=Akaya+Kanadaka&display=swap");
|
||||
@import url("https://fonts.googleapis.com/css2?family=Afacad:ital,wght@0,400..700;1,400..700&display=swap");
|
||||
|
||||
$font-titels: "Akaya Kanadaka", system-ui;
|
||||
|
||||
$font-text: "Afacad", sans-serif;
|
||||
|
||||
@mixin flexbox-center
|
||||
{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
@mixin groene-border
|
||||
{
|
||||
border: solid 2px $primary-color;
|
||||
}
|
||||
|
||||
@mixin box-shadow
|
||||
{
|
||||
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
@mixin border-radius
|
||||
{
|
||||
border-radius: 40px;
|
||||
}
|
||||
|
||||
@mixin inner-border-radius
|
||||
{
|
||||
border-radius: 35px;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5
|
||||
{
|
||||
font-family: $font-titels;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
p,
|
||||
td
|
||||
{
|
||||
font-family: $font-text;
|
||||
color: black;
|
||||
}
|
||||
|
||||
a
|
||||
{
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
body
|
||||
{
|
||||
background: linear-gradient(rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0.5)), url("../images/achtergrond.png");
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
font-family: $font-text;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
|
||||
.mainContainer
|
||||
{
|
||||
width: 85vw;
|
||||
height: 38rem;
|
||||
background-color: rgb(255, 255, 255, 85%);
|
||||
border-radius: 40px;
|
||||
padding: 2rem;
|
||||
|
||||
.goodgarden-logo
|
||||
{
|
||||
position: absolute;
|
||||
width: 10vw;
|
||||
left: 50%;
|
||||
top: 4.1rem;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
.informatie-kas-main-container
|
||||
{
|
||||
display: grid;
|
||||
grid-template-columns: 5fr 7fr;
|
||||
}
|
||||
|
||||
.mainBorder
|
||||
{
|
||||
padding: 1.25rem 1.5rem;
|
||||
padding: 1rem 0;
|
||||
height: 35rem;
|
||||
border: solid 5px $primary-color;
|
||||
border-radius: 40px;
|
||||
|
||||
.pagina-titel
|
||||
{
|
||||
font-size: 2rem;
|
||||
margin-left: 1.5rem;
|
||||
}
|
||||
|
||||
#sectie-1
|
||||
{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
padding: 0 2.5rem 0 1rem;
|
||||
position: relative;
|
||||
|
||||
h1
|
||||
{
|
||||
background-color: green;
|
||||
}
|
||||
|
||||
.parent-algemeen-overzicht
|
||||
{
|
||||
@include box-shadow;
|
||||
@include border-radius;
|
||||
padding: 1rem;
|
||||
margin-top: 1rem;
|
||||
background-color: white;
|
||||
|
||||
.algemeen-overzicht
|
||||
{
|
||||
@include groene-border;
|
||||
@include inner-border-radius;
|
||||
font-size: 1.25rem;
|
||||
padding: 0.5rem 1rem;
|
||||
|
||||
.table-informatie-kas
|
||||
{
|
||||
width: 100%;
|
||||
|
||||
.tr-informatie-kas
|
||||
{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.grafiek
|
||||
{
|
||||
@include box-shadow;
|
||||
@include border-radius;
|
||||
padding: 1rem;
|
||||
position: relative;
|
||||
background-color: white;
|
||||
|
||||
.grafiek-innerbox
|
||||
{
|
||||
@include groene-border;
|
||||
@include inner-border-radius;
|
||||
font-size: 1.25rem;
|
||||
padding: 0 1rem 2.5rem;
|
||||
height: 225px;
|
||||
position: relative;
|
||||
|
||||
h2
|
||||
{
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
canvas
|
||||
{
|
||||
// Zorgt ervoor dat de grafiek precies in eht midden komt
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content
|
||||
{
|
||||
display: grid;
|
||||
grid-template-columns: 3fr 1fr 3fr;
|
||||
height: 100%;
|
||||
|
||||
.kant
|
||||
{
|
||||
&-links
|
||||
{
|
||||
grid-column: 1;
|
||||
|
||||
#planten
|
||||
{
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
|
||||
td
|
||||
{
|
||||
article
|
||||
{
|
||||
height: 7rem;
|
||||
width: 10rem;
|
||||
padding: 0.6rem;
|
||||
margin: 0.1rem;
|
||||
margin-left: 2rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border: solid 3px $primary-color;
|
||||
border-radius: 40px;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
|
||||
#toevoegen
|
||||
{
|
||||
height: 5rem;
|
||||
width: 5rem;
|
||||
}
|
||||
|
||||
h2
|
||||
{
|
||||
color: gray;
|
||||
}
|
||||
|
||||
&:hover
|
||||
{
|
||||
background-color: lightgray;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-rechts
|
||||
{
|
||||
grid-column: 3;
|
||||
// margin-right: 2rem;
|
||||
|
||||
#metingen
|
||||
{
|
||||
border: solid 3px $primary-color;
|
||||
border-radius: 40px;
|
||||
|
||||
#main-waardes
|
||||
{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 0.5rem;
|
||||
padding-bottom: 0;
|
||||
width: 100%;
|
||||
|
||||
table
|
||||
{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.grid-column-2
|
||||
{
|
||||
@include box-shadow;
|
||||
@include border-radius;
|
||||
padding: 1rem;
|
||||
margin: 3.25rem 1rem 1.25rem 1rem;
|
||||
background-color: white;
|
||||
|
||||
.grid-2-child
|
||||
{
|
||||
@include groene-border;
|
||||
@include inner-border-radius;
|
||||
height: 100%;
|
||||
|
||||
.parent-table
|
||||
{
|
||||
padding: 1.5rem 2rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
gap: 2.5rem;
|
||||
justify-content: space-around;
|
||||
height: 90%;
|
||||
|
||||
table
|
||||
{
|
||||
tr
|
||||
{
|
||||
td
|
||||
{
|
||||
font-size: 1.05rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.kas-table-1
|
||||
{
|
||||
tr
|
||||
{
|
||||
td
|
||||
{
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.kas-table-2
|
||||
{
|
||||
position: relative;
|
||||
|
||||
&::after,
|
||||
&::before
|
||||
{
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 1px;
|
||||
width: 90%;
|
||||
background: black;
|
||||
}
|
||||
|
||||
&::after
|
||||
{
|
||||
bottom: -20px;
|
||||
}
|
||||
|
||||
&::before
|
||||
{
|
||||
top: -20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.divider {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
border: solid 1px $primary-color;
|
||||
border-radius: 5px;
|
||||
width: 80%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.modal {
|
||||
display: none;
|
||||
position: fixed;
|
||||
z-index: 999;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
background: white;
|
||||
padding: 1.25rem;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
width: 30vw;
|
||||
height: auto;
|
||||
border: solid 2px #abd3ae;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.modal .close {
|
||||
color: #aaa;
|
||||
float: right;
|
||||
font-size: 1.75rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
.modal .close:hover,
|
||||
.modal .close:active {
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#myModal select,
|
||||
#myModal input {
|
||||
width: calc(100% - 20px);
|
||||
padding: 10px;
|
||||
margin-bottom: 15px;
|
||||
border: 2px solid #abd3ae;
|
||||
border-radius: 5px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#myModal .knop {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
#myModal button {
|
||||
width: 48%;
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
#myModal .knop-container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
#myModal .knop-container input,
|
||||
#myModal .knop-container button {
|
||||
flex: 1;
|
||||
margin: 0 5px;
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#myModal input[type="text"],
|
||||
#myModal select {
|
||||
border: 2px solid #abd3ae;
|
||||
padding: 10px;
|
||||
border-radius: 17px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#myModal input[type="submit"],
|
||||
#myModal button {
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 15px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#myModal input[type="submit"] {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
#myModal button {
|
||||
background-color: white;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.toevoeging {
|
||||
background: linear-gradient(45deg, #abd3ae, #2ecc71);
|
||||
}
|
||||
|
||||
.annulatie-knop {
|
||||
background: linear-gradient(45deg, #ffcc00, #ff6600);
|
||||
}
|
||||
|
||||
#myModal button:hover {
|
||||
background: linear-gradient(45deg, #abd3ae, #fff);
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.modal .close {
|
||||
color: #aaa;
|
||||
float: right;
|
||||
font-size: 1.75rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.modal .close:hover,
|
||||
.modal .close:active {
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.switch-container {
|
||||
display: flex;
|
||||
align-items: end;
|
||||
}
|
||||
|
||||
.switch {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 60px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.switch input {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.slider {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: #ccc;
|
||||
border-radius: 34px;
|
||||
transition: 0.4s;
|
||||
}
|
||||
|
||||
.slider:before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
height: 26px;
|
||||
width: 26px;
|
||||
left: 4px;
|
||||
bottom: 4px;
|
||||
background-color: white;
|
||||
border-radius: 50%;
|
||||
transition: 0.4s;
|
||||
}
|
||||
|
||||
input:checked + .slider {
|
||||
background-color: #2ecc71;
|
||||
}
|
||||
|
||||
input:checked + .slider:before {
|
||||
transform: translateX(26px);
|
||||
}
|
||||
|
||||
.rechterkant {
|
||||
display: flex;
|
||||
justify-content: end;
|
||||
}
|
||||
|
||||
.plant-container,
|
||||
#modalButton
|
||||
{
|
||||
background-color: white;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 107 KiB After Width: | Height: | Size: 107 KiB |
|
Before Width: | Height: | Size: 19 MiB After Width: | Height: | Size: 19 MiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
300
src/py/static/js/main.js
Normal file
@@ -0,0 +1,300 @@
|
||||
// const { ipcRenderer } = require("electron");
|
||||
|
||||
// document.addEventListener('DOMContentLoaded', () =>
|
||||
// {
|
||||
// ipcRenderer.send('request-update-temp', ['some', 'arguments']);
|
||||
|
||||
// ipcRenderer.on('update-temp-result', (event, newTemperature) => {
|
||||
// if (newTemperature === 'error') {
|
||||
// console.error('Er is een fout opgetreden bij het ophalen van de nieuwe temperatuur');
|
||||
// } else {
|
||||
// document.getElementById('bodem-temperatuur').textContent = newTemperature;
|
||||
// }
|
||||
// });
|
||||
|
||||
// });
|
||||
|
||||
// function openModal()
|
||||
// {
|
||||
// const modal = document.getElementById("myModal");
|
||||
// const button = document.getElementById("modalButton");
|
||||
// const close = document.getElementsByClassName("close")[0];
|
||||
|
||||
// // Toon de modal wanneer op de knop wordt geklikt
|
||||
// button.onclick = function()
|
||||
// {
|
||||
// modal.style.display = "block";
|
||||
// }
|
||||
|
||||
// // Sluit de modal wanneer op het 'sluiten' icoon wordt geklikt
|
||||
// close.onclick = function()
|
||||
// {
|
||||
// modal.style.display = "none";
|
||||
// }
|
||||
|
||||
// // Sluit de modal wanneer buiten de modal wordt geklikt
|
||||
// window.onclick = function(event)
|
||||
// {
|
||||
// if (event.target == modal)
|
||||
// {
|
||||
// modal.style.display = "none";
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * --- Functie om de grafiek te tekenen. Enigste belangrijke is de eerste 2 "const" arrays "data" & "xLabels".
|
||||
// */
|
||||
// function drawLineChart()
|
||||
// {
|
||||
// /*Dit is de data die getoond wordt als "punt" op de grafiek. 20 = y20 / x20, 50 = y50 / x50 enzovoort... De array "data" & "xLabels" moeten beide evenveel array items hebben!!*/
|
||||
// const data = [20, 50, 60, 45, 50, 100, 70, 60, 65, 0, 85, 0];
|
||||
// const xLabels = ["", "", "", "", "", 6, "", "", "", "", "", 12];
|
||||
|
||||
// const yLabels = ["", 20, "", 40, "", 60, "", 80, "", 100]; /*NIET VERANDEREN!!!*/
|
||||
|
||||
// const canvas = document.getElementById("myCanvas");
|
||||
// const ctx = canvas.getContext("2d");
|
||||
|
||||
// ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
// const padding = 35; // Increased padding for Y labels
|
||||
// const graphWidth = canvas.width - padding * 2;
|
||||
// const graphHeight = canvas.height - padding * 2;
|
||||
|
||||
// ctx.beginPath();
|
||||
// ctx.moveTo(padding, padding);
|
||||
// ctx.lineTo(padding, canvas.height - padding);
|
||||
// ctx.lineTo(canvas.width - padding, canvas.height - padding);
|
||||
// ctx.stroke();
|
||||
|
||||
// // Set the color of the line
|
||||
// ctx.strokeStyle = "rgb(143, 188, 143)";
|
||||
|
||||
// const xIncrement = graphWidth / (xLabels.length - 1);
|
||||
// const yIncrement = graphHeight / (yLabels.length - 1);
|
||||
|
||||
// // Plot the data
|
||||
// ctx.beginPath();
|
||||
// ctx.moveTo(padding, canvas.height - padding - (data[0] / 100) * graphHeight);
|
||||
|
||||
// for (let i = 1; i < data.length; i++)
|
||||
// {
|
||||
// const xPos = padding + i * xIncrement;
|
||||
// const yPos = canvas.height - padding - (data[i] / 100) * graphHeight;
|
||||
// ctx.lineTo(xPos, yPos);
|
||||
// }
|
||||
// ctx.stroke();
|
||||
|
||||
// // Draw Y labels
|
||||
// ctx.fillStyle = "black";
|
||||
// ctx.textAlign = "right"; // Align text to the right
|
||||
// ctx.textBaseline = "middle"; // Center vertically
|
||||
|
||||
// for (let i = 0; i < yLabels.length; i++)
|
||||
// {
|
||||
// if (yLabels[i] !== "")
|
||||
// {
|
||||
// const yPos = canvas.height - padding - i * yIncrement;
|
||||
// ctx.fillText(yLabels[i], padding - 10, yPos);
|
||||
// }
|
||||
// }
|
||||
|
||||
// // Draw X labels
|
||||
// ctx.textAlign = "center"; // Center horizontally for X labels
|
||||
// for (let i = 0; i < xLabels.length; i++)
|
||||
// {
|
||||
// if (xLabels[i] !== "")
|
||||
// {
|
||||
// const xPos = padding + i * xIncrement;
|
||||
// ctx.fillText(xLabels[i], xPos, canvas.height - padding + 20);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// drawLineChart();
|
||||
|
||||
// /////////////////////////////////
|
||||
|
||||
// // Function to fetch battery data from Flask API
|
||||
// function fetchBatteryData() {
|
||||
// axios.get('http://127.0.0.1:5000')
|
||||
// .then(response => {
|
||||
// const batteryData = response.data;
|
||||
// updateBatteryData(batteryData);
|
||||
// })
|
||||
// .catch(error => {
|
||||
// console.error('Error fetching battery data:', error);
|
||||
// });
|
||||
// }
|
||||
|
||||
// // Function to update HTML content with battery data
|
||||
// function updateBatteryData(batteryData) {
|
||||
// document.getElementById('deviceNumber').innerText = batteryData.device;
|
||||
// document.getElementById('voltage').innerText = batteryData.value;
|
||||
// document.getElementById('time').innerText = batteryData.gateway_receive_time;
|
||||
// document.getElementById('tevredenheid').innerText = batteryData.timestamp;
|
||||
|
||||
// // Voeg andere eigenschappen toe zoals nodig
|
||||
// }
|
||||
|
||||
// // Fetch battery data when the page loads
|
||||
// fetchBatteryData();
|
||||
/////////////////////////////////
|
||||
|
||||
const { ipcRenderer } = require("electron");
|
||||
const axios = require('axios');
|
||||
|
||||
// document.addEventListener('DOMContentLoaded', () => {
|
||||
ipcRenderer.send('request-update-temp', ['some', 'arguments']);
|
||||
|
||||
ipcRenderer.on('update-temp-result', (event, newTemperature) => {
|
||||
if (newTemperature === 'error') {
|
||||
console.error('Er is een fout opgetreden bij het ophalen van de nieuwe temperatuur');
|
||||
} else {
|
||||
document.getElementById('bodem-temperatuur').textContent = newTemperature;
|
||||
}
|
||||
});
|
||||
|
||||
// Send a message to the main process to execute the Python script
|
||||
ipcRenderer.send('run-python-script', ['some', 'arguments']);
|
||||
|
||||
ipcRenderer.on('python-script-response', (event, pythonData) => {
|
||||
if (pythonData === 'error') {
|
||||
console.error('An error occurred while retrieving data from Python');
|
||||
} else {
|
||||
// Update HTML elements with data received from Python
|
||||
document.getElementById('bodem-temperatuur').textContent = pythonData.bodemTemperatuur; // Adjust the property based on your actual Python response
|
||||
}
|
||||
});
|
||||
|
||||
// Listen for updates to HTML data from the main process
|
||||
ipcRenderer.on('update-html-data', (event, data) => {
|
||||
// Update the HTML with the received data
|
||||
document.getElementById('batteryVoltage').innerText = data.batteryVoltage;
|
||||
// Add similar lines for other data fields
|
||||
});
|
||||
|
||||
// Trigger an event to request data update
|
||||
ipcRenderer.send('request-update-data');
|
||||
|
||||
// Function to open the modal
|
||||
function openModal() {
|
||||
const modal = document.getElementById("myModal");
|
||||
const button = document.getElementById("modalButton");
|
||||
const close = document.getElementsByClassName("close")[0];
|
||||
|
||||
// Check if elements are found before attaching events
|
||||
if (modal && button && close) {
|
||||
// Show the modal when the button is clicked
|
||||
button.onclick = function () {
|
||||
modal.style.display = "block";
|
||||
}
|
||||
|
||||
// Close the modal when the 'close' icon is clicked
|
||||
close.onclick = function () {
|
||||
modal.style.display = "none";
|
||||
}
|
||||
|
||||
// Close the modal when clicked outside the modal
|
||||
window.onclick = function (event) {
|
||||
if (event.target == modal) {
|
||||
modal.style.display = "none";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Call the function to open the modal
|
||||
openModal();
|
||||
|
||||
/**
|
||||
* --- Function to draw the chart. The important arrays are "data" & "xLabels".
|
||||
*/
|
||||
function drawLineChart() {
|
||||
const data = [20, 50, 60, 45, 50, 100, 70, 60, 65, 0, 85, 0];
|
||||
const xLabels = ["", "", "", "", "", 6, "", "", "", "", "", 12];
|
||||
const yLabels = ["", 20, "", 40, "", 60, "", 80, "", 100]; /*NIET VERANDEREN!!!*/
|
||||
|
||||
const canvas = document.getElementById("myCanvas");
|
||||
const ctx = canvas.getContext("2d");
|
||||
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
const padding = 35; // Increased padding for Y labels
|
||||
const graphWidth = canvas.width - padding * 2;
|
||||
const graphHeight = canvas.height - padding * 2;
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(padding, padding);
|
||||
ctx.lineTo(padding, canvas.height - padding);
|
||||
ctx.lineTo(canvas.width - padding, canvas.height - padding);
|
||||
ctx.stroke();
|
||||
|
||||
// Set the color of the line
|
||||
ctx.strokeStyle = "rgb(143, 188, 143)";
|
||||
|
||||
const xIncrement = graphWidth / (xLabels.length - 1);
|
||||
const yIncrement = graphHeight / (yLabels.length - 1);
|
||||
|
||||
// Plot the data
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(padding, canvas.height - padding - (data[0] / 100) * graphHeight);
|
||||
|
||||
for (let i = 1; i < data.length; i++) {
|
||||
const xPos = padding + i * xIncrement;
|
||||
const yPos = canvas.height - padding - (data[i] / 100) * graphHeight;
|
||||
ctx.lineTo(xPos, yPos);
|
||||
}
|
||||
ctx.stroke();
|
||||
|
||||
// Draw Y labels
|
||||
ctx.fillStyle = "black";
|
||||
ctx.textAlign = "right"; // Align text to the right
|
||||
ctx.textBaseline = "middle"; // Center vertically
|
||||
|
||||
for (let i = 0; i < yLabels.length; i++) {
|
||||
if (yLabels[i] !== "") {
|
||||
const yPos = canvas.height - padding - i * yIncrement;
|
||||
ctx.fillText(yLabels[i], padding - 10, yPos);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw X labels
|
||||
ctx.textAlign = "center"; // Center horizontally for X labels
|
||||
for (let i = 0; i < xLabels.length; i++) {
|
||||
if (xLabels[i] !== "") {
|
||||
const xPos = padding + i * xIncrement;
|
||||
ctx.fillText(xLabels[i], xPos, canvas.height - padding + 20);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Call the function to draw the line chart
|
||||
drawLineChart();
|
||||
|
||||
// Function to fetch battery data from Flask API
|
||||
function fetchBatteryData() {
|
||||
axios.get('http://127.0.0.1:5000')
|
||||
.then(response => {
|
||||
const batteryData = response.data;
|
||||
updateBatteryData(batteryData);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error fetching battery data:', error);
|
||||
});
|
||||
}
|
||||
|
||||
// Function to update HTML content with battery data
|
||||
function updateBatteryData(batteryData) {
|
||||
document.getElementById('deviceNumber').innerText = batteryData.device;
|
||||
document.getElementById('voltage').innerText = batteryData.value;
|
||||
document.getElementById('time').innerText = batteryData.gateway_receive_time;
|
||||
document.getElementById('zulu').innerText = batteryData.timestamp;
|
||||
|
||||
// Voeg andere eigenschappen toe zoals nodig
|
||||
}
|
||||
|
||||
// Fetch battery data when the page loads
|
||||
fetchBatteryData();
|
||||
// });
|
||||
104
src/py/static/js/planten.class.js
Normal file
@@ -0,0 +1,104 @@
|
||||
class Plant {
|
||||
constructor(dataObject) {
|
||||
this.id = dataObject.id;
|
||||
this.plantNaam = dataObject.plant_naam; // Note the property name change
|
||||
this.plantensoort = dataObject.plantensoort;
|
||||
this.plantGeteelt = dataObject.plant_geteelt;
|
||||
}
|
||||
}
|
||||
|
||||
class PlantGrid {
|
||||
constructor() {
|
||||
this.grid = [];
|
||||
this.cols = 2; // Number of columns
|
||||
this.rows = 4; // Number of rows (including the row for the "Add" button)
|
||||
|
||||
// Initialize the grid with null values
|
||||
for (let i = 0; i < this.rows; i++) {
|
||||
this.grid[i] = new Array(this.cols).fill(null);
|
||||
}
|
||||
|
||||
// Load JSON data from the server
|
||||
this.loadData();
|
||||
}
|
||||
|
||||
loadData() {
|
||||
fetch('../script/plants.json') // Assuming your JSON data is stored in 'plants.json'
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error('Network response was not ok');
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then(data => {
|
||||
const filteredData = data.filter(plantObject => plantObject.plant_geteelt === 1);
|
||||
|
||||
// Populate the grid with plant objects
|
||||
filteredData.slice(0, 8).forEach((plantObject, index) => {
|
||||
const plant = new Plant(plantObject);
|
||||
const col = index % this.cols;
|
||||
const row = Math.floor(index / this.cols);
|
||||
this.grid[row][col] = plant;
|
||||
});
|
||||
|
||||
// Display the grid in the HTML table with id "planten"
|
||||
this.displayGrid();
|
||||
})
|
||||
.catch(error => console.error('Error loading data:', error));
|
||||
}
|
||||
|
||||
displayGrid() {
|
||||
const plantenTable = document.getElementById("planten");
|
||||
|
||||
let itemCount = 0; // Counter for the number of items in the grid
|
||||
|
||||
this.grid.forEach((row, rowIndex) => {
|
||||
const tr = document.createElement("tr");
|
||||
|
||||
row.forEach((plant, colIndex) => {
|
||||
const td = document.createElement("td");
|
||||
|
||||
if (itemCount < 8) {
|
||||
if (plant) {
|
||||
// Handle regular plant items
|
||||
const link = document.createElement("a");
|
||||
link.href = `planteninfo.html?id=${plant.id}`; // Link naar de planteninfo pagina met plant id als query parameter
|
||||
|
||||
const article = document.createElement("article");
|
||||
article.classList.add("plant-container");
|
||||
link.appendChild(article); // Voeg het artikel toe aan de link
|
||||
|
||||
const img = article.appendChild(document.createElement("img"));
|
||||
img.src = "../static/images/icon_awesome-apple-alt.png";
|
||||
const h2 = article.appendChild(document.createElement("h2"));
|
||||
h2.classList.add("plant-naam");
|
||||
h2.textContent = plant.plantNaam;
|
||||
|
||||
td.appendChild(link); // Voeg de link toe aan de td
|
||||
itemCount++;
|
||||
} else if (rowIndex === this.rows - 1 && colIndex === this.cols - 1 && itemCount <= 7) {
|
||||
// Handle the "Add" button
|
||||
const article = document.createElement("article");
|
||||
const img = article.appendChild(document.createElement("img"));
|
||||
img.src = "../static/images/Toevoegen.png";
|
||||
img.id = "toevoegen";
|
||||
img.alt = "Add";
|
||||
article.id = "modalButton";
|
||||
article.onclick = openModal;
|
||||
|
||||
td.appendChild(article);
|
||||
itemCount++;
|
||||
}
|
||||
}
|
||||
|
||||
tr.appendChild(td);
|
||||
});
|
||||
|
||||
plantenTable.appendChild(tr);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
const plantGrid = new PlantGrid();
|
||||
});
|
||||
108
src/py/templates/index.html
Normal file
@@ -0,0 +1,108 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Dashboard / Planten">
|
||||
<meta name="author" content="B. Diker, A. Oomen">
|
||||
<meta name="keywords" content="planten / kas">
|
||||
<title>Dashboard</title>
|
||||
<link rel="stylesheet" href="../static/css/style.css">
|
||||
<script src="../static/js/main.js" defer></script>
|
||||
<script src="../static/js/planten.class.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<section class="mainContainer">
|
||||
<article>
|
||||
<a href="index.html">
|
||||
<img src="../static/images/logo.png" class="goodgarden-logo">
|
||||
</a>
|
||||
</article>
|
||||
<section class="mainBorder">
|
||||
<section class="content">
|
||||
<section class="kant-links">
|
||||
<table id="planten">
|
||||
<!-- <tr>
|
||||
<td>
|
||||
<article>
|
||||
<img src="images/Icon awesome-apple-alt.png" alt="">
|
||||
<h2>Tomaat</h2>
|
||||
</article>
|
||||
</td>
|
||||
</tr> -->
|
||||
</table>
|
||||
<div class="formulier">
|
||||
<div id="myModal" class="modal" style="display: none;">
|
||||
<h1 id="plant-id">Plant Toevoegen</h1>
|
||||
<form action="http://localhost:3000/submit-form" method="post">
|
||||
<label for="plantNaam">Naam van de plant</label><br>
|
||||
<input type="text" name="plant_naam" id="plantNaam"><br>
|
||||
|
||||
<label for="plantensoort">Soort van de plant</label><br>
|
||||
<input type="text" name="plantensoort" id="plantensoort"><br>
|
||||
|
||||
<label for="aanwezig">Aanwezig in de kas</label><br>
|
||||
<select name="aanwezig_in_kas">
|
||||
<option value="ja">Ja</option>
|
||||
<option value="nee">Nee</option>
|
||||
</select><br>
|
||||
|
||||
<label for="ontvangenMeldingen">Meldingen ontvangen</label><br>
|
||||
<select name="ontvangen_meldingen">
|
||||
<option value="ja">Ja</option>
|
||||
<option value="nee">Nee</option>
|
||||
</select><br>
|
||||
|
||||
<section class="knop-container">
|
||||
<br><button class="annulatie-knop" type="button" onclick="closeOverlay()">Annuleren</button>
|
||||
<input type="submit" value="Submit">
|
||||
</section>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div id="overlay" onclick="closeOverlay()"></div>
|
||||
</section>
|
||||
<!-- White space -->
|
||||
<section>
|
||||
</section>
|
||||
<section class="kant-rechts">
|
||||
<section id="sectie-1">
|
||||
<article class="parent-algemeen-overzicht">
|
||||
<article class="algemeen-overzicht">
|
||||
<a href="kas_informatie.html">
|
||||
<table class="table-informatie-kas">
|
||||
<tr class="tr-informatie-kas">
|
||||
<td>Dagen tot Oogst</td>
|
||||
<td>12</td>
|
||||
</tr>
|
||||
<tr class="tr-informatie-kas">
|
||||
<td>Dagen in Kas</td>
|
||||
<td>2</td>
|
||||
</tr>
|
||||
<tr class="tr-informatie-kas">
|
||||
<td>Tevredenheid</td>
|
||||
<td>80%</td>
|
||||
</tr>
|
||||
<tr class="tr-informatie-kas">
|
||||
<td>Aandachtspunten</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
</table>
|
||||
<a/>
|
||||
</article>
|
||||
</article>
|
||||
<article class="grafiek">
|
||||
<article class="grafiek-innerbox">
|
||||
<h2>Zonlicht</h2>
|
||||
<canvas
|
||||
id="myCanvas" class="canvas-informatie-kas" width="275" height="275"></canvas>
|
||||
</article>
|
||||
</article>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
126
src/py/templates/kas_informatie.html
Normal file
@@ -0,0 +1,126 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="description" content="Kas informatie / Planten" />
|
||||
<meta name="author" content="B. Diker, A. Oomen" />
|
||||
<meta name="keywords" content="planten / kas" />
|
||||
<link rel="stylesheet" href="../static/css/style.css" />
|
||||
<script src="../static/js/main.js" defer></script>
|
||||
<title>Informatie Kas</title>
|
||||
</head>
|
||||
<body>
|
||||
<section class="mainContainer">
|
||||
<article>
|
||||
<a href="index.html">
|
||||
<img src="../static/images/logo.png" class="goodgarden-logo">
|
||||
</a>
|
||||
</article>
|
||||
<section class="mainBorder informatie-kas-main-container">
|
||||
<article>
|
||||
<h1 class="pagina-titel">Informatie Kas</h1>
|
||||
<section id="sectie-1">
|
||||
<article class="parent-algemeen-overzicht">
|
||||
<article class="algemeen-overzicht">
|
||||
<table class="table-informatie-kas">
|
||||
<tr class="tr-informatie-kas">
|
||||
<td>Device</td>
|
||||
<td id="deviceNumber"></td> <!-- Update this ID -->
|
||||
</tr>
|
||||
<tr class="tr-informatie-kas">
|
||||
<td>Batterij Voltage</td>
|
||||
<td id="voltage"></td> <!-- Update this ID -->
|
||||
</tr>
|
||||
<tr class="tr-informatie-kas">
|
||||
<td>Tijden</td>
|
||||
<td id="time"></td> <!-- Update this ID -->
|
||||
</tr>
|
||||
<tr class="tr-informatie-kas">
|
||||
<td>Zulu</td>
|
||||
<td id="zulu"></td> <!-- Update this ID -->
|
||||
</tr>
|
||||
</table>
|
||||
</article>
|
||||
</article>
|
||||
<article class="grafiek">
|
||||
<article class="grafiek-innerbox">
|
||||
<h2>Zonlicht</h2>
|
||||
<canvas
|
||||
id="myCanvas"
|
||||
class="canvas-informatie-kas"
|
||||
width="275"
|
||||
height="275"
|
||||
></canvas>
|
||||
</article>
|
||||
</article>
|
||||
</section>
|
||||
</article>
|
||||
<article class="grid-column-2">
|
||||
<article class="grid-2-child">
|
||||
<section class="parent-table">
|
||||
<table class="kas-table-1">
|
||||
<tr>
|
||||
<td>Aantal geplant:</td>
|
||||
<td id="totale_planten">Loading...</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Succesvolle Oogst:</td>
|
||||
<td>2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Gefaalde Oogst:</td>
|
||||
<td>2</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table class="kas-table-2">
|
||||
<tr>
|
||||
<td>Warmste Maand:</td>
|
||||
<td>n.v.t.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>koudste Maand:</td>
|
||||
<td>December</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Gemiddelde Bodemtemp.:</td>
|
||||
<td id="bodem-temperatuur">2˚C</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Gemiddelde Uren Zonlicht:</td>
|
||||
<td id="battery_voltage">2u</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table class="kas-table-3">
|
||||
<tr>
|
||||
<td>Laatste Irrigatie:</td>
|
||||
<td>2u</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Aankomende Irrigatie:</td>
|
||||
<td>2u</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Laatste Bemesting</td>
|
||||
<td>2d</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Aankomende Bemesting:</td>
|
||||
<td>2w</td>
|
||||
</tr>
|
||||
</table>
|
||||
</section>
|
||||
</article>
|
||||
</article>
|
||||
</section>
|
||||
</section>
|
||||
<script>
|
||||
// fetch('get_data.php')
|
||||
// .then(response => response.json())
|
||||
// .then(data => {
|
||||
// document.getElementById('totale_planten').innerHTML = data.totale_planten;
|
||||
// })
|
||||
// .catch(error => console.error('Error:', error));
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
118
src/py/templates/planteninfo.html
Normal file
@@ -0,0 +1,118 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="description" content="Planteninfo / Planten" />
|
||||
<meta name="author" content="B. Diker, A. Oomen" />
|
||||
<meta name="keywords" content="planten / kas" />
|
||||
<link rel="stylesheet" href="../static/css/style.css" />
|
||||
<script src="../static/js/main.js" defer></script>
|
||||
<title>Informatie Kas</title>
|
||||
</head>
|
||||
<body>
|
||||
<section class="mainContainer">
|
||||
<article>
|
||||
<a href="index.html">
|
||||
<img src="../static/images/logo.png" class="goodgarden-logo">
|
||||
</a>
|
||||
</article>
|
||||
<section class="mainBorder informatie-kas-main-container">
|
||||
<article>
|
||||
<h1>Informatie Kas</h1>
|
||||
<section id="sectie-1">
|
||||
<article class="parent-algemeen-overzicht">
|
||||
<article class="algemeen-overzicht">
|
||||
<table class="table-informatie-kas">
|
||||
<tr class="tr-informatie-kas">
|
||||
<td>Dagen tot Oogst</td>
|
||||
<td>12</td>
|
||||
</tr>
|
||||
<tr class="tr-informatie-kas">
|
||||
<td>Dagen in Kas</td>
|
||||
<td>2</td>
|
||||
</tr>
|
||||
<tr class="tr-informatie-kas">
|
||||
<td>Tevredenheid</td>
|
||||
<td>80%</td>
|
||||
</tr>
|
||||
<tr class="tr-informatie-kas">
|
||||
<td>Aandachtspunten</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
</table>
|
||||
</article>
|
||||
</article>
|
||||
<article class="grafiek">
|
||||
<article class="grafiek-innerbox">
|
||||
<h2>Zonlicht</h2>
|
||||
<canvas
|
||||
id="myCanvas"
|
||||
class="canvas-informatie-kas"
|
||||
width="275"
|
||||
height="275"
|
||||
></canvas>
|
||||
</article>
|
||||
</article>
|
||||
</section>
|
||||
</article>
|
||||
<article class="grid-column-2">
|
||||
<article class="grid-2-child">
|
||||
<section class="parent-table">
|
||||
<table class="kas-table-1">
|
||||
<tr>
|
||||
<td>Aantal geplant:</td>
|
||||
<td>2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Succesvolle Oogst:</td>
|
||||
<td>2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Gefaalde Oogst:</td>
|
||||
<td>2</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table class="kas-table-2">
|
||||
<tr>
|
||||
<td>Warmste Maand:</td>
|
||||
<td>n.v.t.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>koudste Maand:</td>
|
||||
<td>December</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Gemiddelde Bodemtemp.:</td>
|
||||
<td id="bodem-temperatuur">2˚C</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Gemiddelde Uren Zonlicht:</td>
|
||||
<td id="battery_voltage">2u</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table class="kas-table-3">
|
||||
<tr>
|
||||
<td>Laatste Irrigatie:</td>
|
||||
<td>2u</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Aankomende Irrigatie:</td>
|
||||
<td>2u</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Laatste Bemesting</td>
|
||||
<td>2d</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Aankomende Bemesting:</td>
|
||||
<td>2w</td>
|
||||
</tr>
|
||||
</table>
|
||||
</section>
|
||||
</article>
|
||||
</article>
|
||||
</section>
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
||||