This commit is contained in:
Renzo
2024-03-06 11:14:09 +01:00
15 changed files with 1124 additions and 392 deletions

9
app.js
View File

@@ -1,7 +1,7 @@
const { app, BrowserWindow } = require('electron'); /* TYPE IN TERMINAL: "npm install electron" */ const { app, BrowserWindow, ipcMain } = require('electron');
const express = require('express'); /* TYPE IN TERMINAL: "npm install express" */ const express = require('express');
const bodyParser = require('body-parser'); /* TYPE IN TERMINAL: "npm install body-parser" */ const bodyParser = require('body-parser');
const { PythonShell } = require('python-shell'); /* TYPE IN TERMINAL: "npm install python-shell" */ const { PythonShell } = require('python-shell');
const path = require('path'); const path = require('path');
const urlElectron = path.join(__dirname, "src/index.html"); const urlElectron = path.join(__dirname, "src/index.html");
@@ -42,6 +42,7 @@ function createWindow() {
const mainWindow = new BrowserWindow({ const mainWindow = new BrowserWindow({
width: 1280, width: 1280,
height: 800, height: 800,
frame: false,
webPreferences: { webPreferences: {
nodeIntegration: true, nodeIntegration: true,
contextIsolation: false contextIsolation: false

106
package-lock.json generated
View File

@@ -10,7 +10,7 @@
"dependencies": { "dependencies": {
"body-parser": "^1.20.2", "body-parser": "^1.20.2",
"elctron": "^0.0.1-security", "elctron": "^0.0.1-security",
"express": "^4.18.2", "express": "^4.18.3",
"mysql2": "^3.9.1", "mysql2": "^3.9.1",
"python-shell": "^5.0.0" "python-shell": "^5.0.0"
}, },
@@ -896,13 +896,13 @@
} }
}, },
"node_modules/express": { "node_modules/express": {
"version": "4.18.2", "version": "4.18.3",
"resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", "resolved": "https://registry.npmjs.org/express/-/express-4.18.3.tgz",
"integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", "integrity": "sha512-6VyCijWQ+9O7WuVMTRBTl+cjNNIzD5cY5mQ1WM8r/LEkI2u8EYpOotESNwzNlyCn3g+dmjKYI6BmNneSr/FSRw==",
"dependencies": { "dependencies": {
"accepts": "~1.3.8", "accepts": "~1.3.8",
"array-flatten": "1.1.1", "array-flatten": "1.1.1",
"body-parser": "1.20.1", "body-parser": "1.20.2",
"content-disposition": "0.5.4", "content-disposition": "0.5.4",
"content-type": "~1.0.4", "content-type": "~1.0.4",
"cookie": "0.5.0", "cookie": "0.5.0",
@@ -936,54 +936,6 @@
"node": ">= 0.10.0" "node": ">= 0.10.0"
} }
}, },
"node_modules/express/node_modules/body-parser": {
"version": "1.20.1",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
"integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
"dependencies": {
"bytes": "3.1.2",
"content-type": "~1.0.4",
"debug": "2.6.9",
"depd": "2.0.0",
"destroy": "1.2.0",
"http-errors": "2.0.0",
"iconv-lite": "0.4.24",
"on-finished": "2.4.1",
"qs": "6.11.0",
"raw-body": "2.5.1",
"type-is": "~1.6.18",
"unpipe": "1.0.0"
},
"engines": {
"node": ">= 0.8",
"npm": "1.2.8000 || >= 1.4.16"
}
},
"node_modules/express/node_modules/iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/express/node_modules/raw-body": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
"integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
"dependencies": {
"bytes": "3.1.2",
"http-errors": "2.0.0",
"iconv-lite": "0.4.24",
"unpipe": "1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/extract-zip": { "node_modules/extract-zip": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz",
@@ -2339,13 +2291,13 @@
"integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="
}, },
"express": { "express": {
"version": "4.18.2", "version": "4.18.3",
"resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", "resolved": "https://registry.npmjs.org/express/-/express-4.18.3.tgz",
"integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", "integrity": "sha512-6VyCijWQ+9O7WuVMTRBTl+cjNNIzD5cY5mQ1WM8r/LEkI2u8EYpOotESNwzNlyCn3g+dmjKYI6BmNneSr/FSRw==",
"requires": { "requires": {
"accepts": "~1.3.8", "accepts": "~1.3.8",
"array-flatten": "1.1.1", "array-flatten": "1.1.1",
"body-parser": "1.20.1", "body-parser": "1.20.2",
"content-disposition": "0.5.4", "content-disposition": "0.5.4",
"content-type": "~1.0.4", "content-type": "~1.0.4",
"cookie": "0.5.0", "cookie": "0.5.0",
@@ -2374,46 +2326,6 @@
"type-is": "~1.6.18", "type-is": "~1.6.18",
"utils-merge": "1.0.1", "utils-merge": "1.0.1",
"vary": "~1.1.2" "vary": "~1.1.2"
},
"dependencies": {
"body-parser": {
"version": "1.20.1",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
"integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
"requires": {
"bytes": "3.1.2",
"content-type": "~1.0.4",
"debug": "2.6.9",
"depd": "2.0.0",
"destroy": "1.2.0",
"http-errors": "2.0.0",
"iconv-lite": "0.4.24",
"on-finished": "2.4.1",
"qs": "6.11.0",
"raw-body": "2.5.1",
"type-is": "~1.6.18",
"unpipe": "1.0.0"
}
},
"iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
"requires": {
"safer-buffer": ">= 2.1.2 < 3"
}
},
"raw-body": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
"integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
"requires": {
"bytes": "3.1.2",
"http-errors": "2.0.0",
"iconv-lite": "0.4.24",
"unpipe": "1.0.0"
}
}
} }
}, },
"extract-zip": { "extract-zip": {

View File

@@ -14,7 +14,7 @@
"dependencies": { "dependencies": {
"body-parser": "^1.20.2", "body-parser": "^1.20.2",
"elctron": "^0.0.1-security", "elctron": "^0.0.1-security",
"express": "^4.18.2", "express": "^4.18.3",
"mysql2": "^3.9.1", "mysql2": "^3.9.1",
"python-shell": "^5.0.0" "python-shell": "^5.0.0"
} }

123
script/DUMMY.json Normal file
View File

@@ -0,0 +1,123 @@
// 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": [
{
"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,
"gateway_receive_time": "2024-02-13T15:17:40Z",
"device": 322,
"value": 4.105006217956543
}
],
"devices": [
{
"id": 256,
"serial_number": "0033889B1BAB1169",
"name": "firefly2_0051",
"label": "The Field",
"last_seen": 1707765066,
"last_battery_voltage": 4.09768009185791
},
{
"id": 322,
"serial_number": "006FE1FC316ED7D8",
"name": "firefly2_0111",
"label": "The Field",
"last_seen": 1707764966,
"last_battery_voltage": 4.107448101043701
}
],
// Fotosyntese??? (zonlicht)
"par_events": [
{
"timestamp": 1707844638,
"gateway_receive_time": "2024-02-13T17:17:18Z",
"device": 322,
"value": 0.0
},
{
"timestamp": 1707851099,
"gateway_receive_time": "2024-02-13T19:04:59Z",
"device": 256,
"value": 0.0
}
],
// Luchtvochtigheid
"relative_humidity_events": [
{
"timestamp": 1707844638,
"gateway_receive_time": "2024-02-13T17:17:18Z",
"device": 322,
"value": 71.08984375
},
{
"timestamp": 1707851099,
"gateway_receive_time": "2024-02-13T19:04:59Z",
"device": 256,
"value": 66.7294921875
}
],
// 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,
"gateway_receive_time": "2024-02-13T19:06:55Z",
"device": 322,
"value": 0.0
}
],
// 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,
"gateway_receive_time": "2024-02-13T19:06:55Z",
"device": 322,
"value": 12.06
}
]
}

View File

@@ -1,52 +1,276 @@
import requests #** TYPE IN TERMINAL: "pip install requests" # import requests #** TYPE IN TERMINAL: "pip install requests"
import time # import time
import mysql.connector #** TYPE IN TERMINAL: "pip install mysql-connector-python" # import mysql.connector #** TYPE IN TERMINAL: "pip install mysql-connector-python"
# Import python db_connect.py script # # Import python db_connect.py script
from db_connect import database_connect # 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():
return mysql.connector.connect(
host="localhost",
user="root",
password="",
database="goodgarden"
)
def calculate_timestamp(gateway_receive_time):
# Converteer de stringrepresentatie naar een datetime-object in UTC
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)
# 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 # Functie voor het aanmaken van gegevens in de database
def create_data(url, access_token, repeat_count=5): def create_data(url, access_token, repeat_count=5):
for _ in range(repeat_count): for _ in range(repeat_count):
try: try:
headers = { headers = {"Authorization": f"Token {access_token}"}
"Authorization": f"Token {access_token}"
}
response = requests.get(url, headers=headers) response = requests.get(url, headers=headers)
response.raise_for_status() response.raise_for_status()
data = response.json() data = response.json()
print(f"Data from {url}:\n")
# print(f"Data from {url}:") # Check if data is a list (records directly under the root)
print(data) if isinstance(data, list):
insert_data(data) records = data
elif isinstance(data, dict) and 'results' in data:
except requests.exceptions.RequestException as e: records = data['results']
print(f"Error fetching data from {url}: {e}") else:
print(f"Unexpected data format received: {data}")
print("Waiting for the next create action...") continue
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
for record in records:
# Now, record is assumed to be a dictionary
timestamp = record.get('timestamp', '') timestamp = record.get('timestamp', '')
gateway_receive_time = record.get('gateway_receive_time', '') gateway_receive_time = record.get('gateway_receive_time', '')
device = record.get('device', '') device = record.get('device', '')
value = record.get('value', '') value = record.get('value', '')
print(f"Inserting data: timestamp={timestamp}, gateway_receive_time={gateway_receive_time}, device={device}, value={value}") # Voeg de timestamp-berekening toe
calculated_timestamp = calculate_timestamp(gateway_receive_time)
print(f"\nInserted data: Timestamp: {calculated_timestamp}, Device: {device}, Battery Voltage: {value}V")
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(2)
# 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 = calculate_timestamp(record.get('gateway_receive_time', ''))
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
# Voer de query uit # Voer de query uit
mycursor.execute(insert_query, (timestamp, gateway_receive_time, device, value)) mycursor.execute(insert_query, (timestamp, gateway_receive_time, device, value))
@@ -58,29 +282,41 @@ def insert_data(data):
mycursor.close() mycursor.close()
mydb.close() mydb.close()
print("Data inserted into the database.")
# Functie voor het lezen van gegevens uit de database # Functie voor het lezen van gegevens uit de database
def read_data(url, access_token, repeat_count=5): def read_data(url, access_token, repeat_count=5):
for _ in range(repeat_count): for _ in range(repeat_count):
try: try:
headers = { headers = {"Authorization": f"Token {access_token}"}
"Authorization": f"Token {access_token}"
}
response = requests.get(url, headers=headers) response = requests.get(url, headers=headers)
response.raise_for_status() response.raise_for_status()
data = response.json() data = response.json()
print(f"Data from {url}:") print(f"Data from {url}:\n")
print(data)
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: except requests.exceptions.RequestException as e:
print(f"Error fetching data from {url}: {e}") print(f"Error fetching data from {url}: {e}")
# Wacht een bepaalde tijd in secondes print("Waiting for the next read action...\n")
print("Waiting for the next read action...")
time.sleep(300) time.sleep(300)
# Functie voor het bijwerken van gegevens in de database # Functie voor het bijwerken van gegevens in de database
def update_data(record_id, new_value): def update_data(record_id):
try: try:
mydb = database_connect() mydb = database_connect()
@@ -95,18 +331,24 @@ def update_data(record_id, new_value):
print(f"Record with ID {record_id} not found. Update operation aborted.") print(f"Record with ID {record_id} not found. Update operation aborted.")
return 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 # Hier moet je de juiste kolomnamen aanpassen op basis van de structuur van je database
update_query = """ update_query = """
UPDATE goodgarden.battery_voltage_events UPDATE goodgarden.battery_voltage_events
SET value = %s SET timestamp = %s, gateway_receive_time = %s, device = %s, value = %s
WHERE id = %s WHERE id = %s
""" """
# Voer de query uit # Voer de query uit
print(f"Executing update query: {update_query}") print(f"Executing update query: {update_query}")
print(f"Updating record with ID {record_id} to new value: {new_value}") 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_value, record_id)) # Provide the tuple with values here mycursor.execute(update_query, (new_timestamp, new_gateway_receive_time, new_device, new_value, record_id))
# Bevestig de wijzigingen # Bevestig de wijzigingen
mydb.commit() mydb.commit()
@@ -122,7 +364,6 @@ def update_data(record_id, new_value):
if 'mydb' in locals() and mydb.is_connected(): if 'mydb' in locals() and mydb.is_connected():
mydb.close() mydb.close()
# Functie voor het verwijderen van gegevens uit de database # Functie voor het verwijderen van gegevens uit de database
def delete_data(record_id): def delete_data(record_id):
mydb = database_connect() mydb = database_connect()
@@ -147,32 +388,31 @@ def delete_data(record_id):
print(f"Data with ID {record_id} deleted.") print(f"Data with ID {record_id} deleted.")
# Functie voor het aanmaken van gegevens in de database op basis van batterijspanningsinformatie
if __name__ == "__main__": if __name__ == "__main__":
url = "https://garden.inajar.nl/api/battery_voltage_events/?format=json" url = "https://garden.inajar.nl/api/battery_voltage_events/?format=json"
access_token = "33bb3b42452306c58ecedc3c86cfae28ba22329c" 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 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() 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": if operation_choice == "C":
# Maak gegevens aan
create_data(url, access_token, repeat_count) create_data(url, access_token, repeat_count)
# Lees gegevens
elif operation_choice == "R": elif operation_choice == "R":
# Lees gegevens
read_data(url, access_token, repeat_count) read_data(url, access_token, repeat_count)
# Update gegevens
elif operation_choice == "U": elif operation_choice == "U":
# Update gegevens
record_id = int(input("Enter record ID to update: ")) record_id = int(input("Enter record ID to update: "))
new_value = input("Enter new value: ") # Call the update_data function without additional arguments
update_data(record_id, new_value) update_data(record_id)
# Verwijder gegevens
elif operation_choice == "D": elif operation_choice == "D":
# Verwijder gegevens
record_id = int(input("Enter record ID to delete: ")) record_id = int(input("Enter record ID to delete: "))
delete_data(record_id) delete_data(record_id)
else: else:
print("Invalid operation choice. Please choose C, R, U, or D.") print("Invalid operation choice. Please choose C, R, U, or D.")

View File

@@ -1,27 +0,0 @@
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";
}
}
}

View File

@@ -1,40 +1,123 @@
/*default colors*/
@import url("https://fonts.googleapis.com/css2?family=Akaya+Kanadaka&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"); @import url("https://fonts.googleapis.com/css2?family=Afacad:ital,wght@0,400..700;1,400..700&display=swap");
/* The Main container and border*/ h1, h2, h3, h4, h5 {
font-family: "Akaya Kanadaka", system-ui;
margin: 0;
}
p, td {
font-family: "Afacad", sans-serif;
}
body { body {
background-image: url("../images/achtergrond.png"); background-image: url("../images/achtergrond.png");
background-repeat: no-repeat; background-repeat: no-repeat;
background-size: cover; background-size: cover;
background-position: center;
font-family: "Afacad", sans-serif; font-family: "Afacad", sans-serif;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
} }
body .mainContainer {
.mainContainer { width: 85vw;
margin: 2rem;
height: 38rem; height: 38rem;
background-color: rgba(255, 255, 255, 0.95); background-color: rgba(255, 255, 255, 0.95);
border-radius: 40px; border-radius: 40px;
padding: 2rem; padding: 2rem;
} }
.mainContainer .mainBorder { 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; padding: 1rem 0;
height: 35rem; height: 35rem;
border: solid 5px rgb(171, 211, 174); border: solid 5px rgb(171, 211, 174);
border-radius: 40px; border-radius: 40px;
} }
.mainContainer .mainBorder .content { 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;
}
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;
}
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; display: grid;
grid-template-columns: 3fr 1fr 3fr; grid-template-columns: 3fr 1fr 3fr;
height: 100%; height: 100%;
} }
.mainContainer .mainBorder .content .kant-links { body .mainContainer .mainBorder .content .kant-links {
grid-column: 1; grid-column: 1;
} }
.mainContainer .mainBorder .content .kant-links #planten { body .mainContainer .mainBorder .content .kant-links #planten {
width: 100%; width: 100%;
border-collapse: collapse; border-collapse: collapse;
} }
.mainContainer .mainBorder .content .kant-links #planten td article { body .mainContainer .mainBorder .content .kant-links #planten td article {
height: 7rem; height: 7rem;
width: 10rem; width: 10rem;
padding: 0.6rem; padding: 0.6rem;
@@ -48,34 +131,71 @@ body {
border-radius: 40px; border-radius: 40px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
} }
.mainContainer .mainBorder .content .kant-links #planten td article #toevoegen { body .mainContainer .mainBorder .content .kant-links #planten td article #toevoegen {
height: 5rem; height: 5rem;
width: 5rem; width: 5rem;
} }
.mainContainer .mainBorder .content .kant-links #planten td article h2 { body .mainContainer .mainBorder .content .kant-links #planten td article h2 {
color: gray; color: gray;
} }
.mainContainer .mainBorder .content .kant-links #planten td article:hover { body .mainContainer .mainBorder .content .kant-links #planten td article:hover {
background-color: lightgray; background-color: lightgray;
} }
.mainContainer .mainBorder .content .kant-rechts { body .mainContainer .mainBorder .content .kant-rechts {
grid-column: 3; grid-column: 3;
margin-right: 2rem; margin-right: 2rem;
} }
.mainContainer .mainBorder .content .kant-rechts #metingen { body .mainContainer .mainBorder .content .kant-rechts #metingen {
border: solid 3px rgb(171, 211, 174); border: solid 3px rgb(171, 211, 174);
border-radius: 40px; border-radius: 40px;
} }
.mainContainer .mainBorder .content .kant-rechts #metingen #main-waardes { body .mainContainer .mainBorder .content .kant-rechts #metingen #main-waardes {
display: flex; display: flex;
justify-content: space-evenly; justify-content: space-between;
padding: 0.5rem; padding: 0.5rem;
padding-bottom: 0; padding-bottom: 0;
width: 100%; width: 100%;
} }
.mainContainer .mainBorder .content .kant-rechts #metingen #main-waardes table { body .mainContainer .mainBorder .content .kant-rechts #metingen #main-waardes table {
display: flex; 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;
}
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;
justify-content: space-around; justify-content: space-around;
height: 90%;
}
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 */ /* Divider */
@@ -97,7 +217,7 @@ body {
top: 50%; top: 50%;
transform: translate(-50%, -50%); transform: translate(-50%, -50%);
background: white; background: white;
padding: 20px; padding: 1.25rem;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
width: 30vw; width: 30vw;
height: auto; height: auto;
@@ -107,7 +227,7 @@ body {
.modal .close { .modal .close {
color: #aaa; color: #aaa;
float: right; float: right;
font-size: 28px; font-size: 1.75rem;
font-weight: bold; font-weight: bold;
} }
.modal .close:hover, .modal .close:active { .modal .close:hover, .modal .close:active {

View File

@@ -1 +1 @@
{"version":3,"sources":["style.scss","style.css"],"names":[],"mappings":"AAAA,iBAAA;AAKQ,mFAAA;AACA,2GAAA;AAMR,iCAAA;AACA;EAEI,kDAAA;EACA,4BAAA;EACA,sBAAA;EACA,iCARQ;ACDZ;;ADYA;EAEI,YAAA;EACA,aAAA;EACA,2CAAA;EACA,mBAAA;EACA,aAAA;ACVJ;ADYI;EAEI,eAAA;EACA,aAAA;EACA,oCAAA;EACA,mBAAA;ACXR;ADaQ;EAEI,aAAA;EACA,kCAAA;EACA,YAAA;ACZZ;ADgBgB;EAEI,cAAA;ACfpB;ADiBoB;EAEI,WAAA;EACA,yBAAA;AChBxB;ADoB4B;EAEI,YAAA;EACA,YAAA;EACA,eAAA;EACA,cAAA;EACA,iBAAA;EACA,aAAA;EACA,sBAAA;EACA,uBAAA;EACA,mBAAA;EACA,oCAAA;EACA,mBAAA;EACA,wCAAA;ACnBhC;ADqBgC;EAEI,YAAA;EACA,WAAA;ACpBpC;ADuBgC;EAEI,WAAA;ACtBpC;ADyBgC;EAEI,2BAAA;ACxBpC;AD+BgB;EAEI,cAAA;EACA,kBAAA;AC9BpB;ADgCoB;EAGI,oCAAA;EACA,mBAAA;AChCxB;ADkCwB;EAEA,aAAA;EACA,6BAAA;EACA,eAAA;EACA,iBAAA;EACA,WAAA;ACjCxB;ADmC4B;EAEI,aAAA;EACA,6BAAA;AClChC;;AD6CA,YAAA;AACA;EACI,aAAA;EACA,uBAAA;EACA,oCAAA;EACA,kBAAA;EACA,UAAA;EACA,cAAA;AC1CJ;;AD6CA,2BAAA;AAEA;EAEI,aAAA;EACA,eAAA;EACA,YAAA;EACA,SAAA;EACA,QAAA;EACA,gCAAA;EACA,iBAAA;EACA,aAAA;EACA,wCAAA;EACA,WAAA;EACA,YAAA;EACA,uBAAA;EACA,mBAAA;AC5CJ;AD8CI;EAEI,WAAA;EACA,YAAA;EACA,eAAA;EACA,iBAAA;AC7CR;AD+CQ;EAGI,YAAA;EACA,qBAAA;EACA,eAAA;AC/CZ","file":"style.css"} {"version":3,"sources":["style.scss","style.css"],"names":[],"mappings":"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","file":"style.css"}

View File

@@ -1,5 +1,3 @@
/*default colors*/
$primary-color: rgb(171, 211, 174); $primary-color: rgb(171, 211, 174);
$secondary-color: rgb(143, 188, 143); $secondary-color: rgb(143, 188, 143);
@@ -7,6 +5,7 @@ $secondary-color: rgb(143, 188, 143);
@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=Afacad:ital,wght@0,400..700;1,400..700&display=swap');
$font-titels: "Akaya Kanadaka", system-ui; $font-titels: "Akaya Kanadaka", system-ui;
$font-text: "Afacad", sans-serif; $font-text: "Afacad", sans-serif;
@mixin flexbox @mixin flexbox
@@ -30,6 +29,11 @@ $font-text: "Afacad", sans-serif;
border-radius: 40px; border-radius: 40px;
} }
@mixin inner-border-radius
{
border-radius: 35px;
}
h1, h2, h3, h4, h5 h1, h2, h3, h4, h5
{ {
font-family: $font-titels; font-family: $font-titels;
@@ -47,7 +51,7 @@ body
background-repeat: no-repeat; background-repeat: no-repeat;
background-size: cover; background-size: cover;
background-position: center; background-position: center;
// font-family: $font-text; font-family: $font-text;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
@@ -62,6 +66,15 @@ body
border-radius: 40px; border-radius: 40px;
padding: 2rem; padding: 2rem;
.goodgarden-logo
{
position: absolute;
width: 10vw;
left: 50%;
top: 4.1rem;
transform: translateX(-50%);
}
.informatie-kas-main-container .informatie-kas-main-container
{ {
display: grid; display: grid;
@@ -70,13 +83,26 @@ body
.mainBorder .mainBorder
{ {
padding: 1.25rem 1.5rem;
padding: 1rem 0; padding: 1rem 0;
height: 35rem; height: 35rem;
border: solid 5px $primary-color; border: solid 5px $primary-color;
border-radius: 40px; border-radius: 40px;
.pagina-titel
{
font-size: 2rem;
margin-left: 1.5rem;
}
#sectie-1 #sectie-1
{ {
display: flex;
flex-direction: column;
gap: 1rem;
padding: 0 2.5rem 0 1rem;
position: relative;
h1 h1
{ {
background-color: green; background-color: green;
@@ -87,14 +113,15 @@ body
@include box-shadow; @include box-shadow;
@include border-radius; @include border-radius;
padding: 1rem; padding: 1rem;
margin-top: 1rem;
.algemeen-overzicht .algemeen-overzicht
{ {
@include groene-border; @include groene-border;
@include border-radius; @include inner-border-radius;
font-size: 1.25rem; font-size: 1.25rem;
padding: 1rem; padding: .5rem 1rem;
background-color: red;
.table-informatie-kas .table-informatie-kas
{ {
@@ -106,22 +133,45 @@ body
justify-content: space-between; justify-content: space-between;
text-align: left; text-align: left;
} }
}
// .tr-informatie-kas > :last-child
// {
// text-align: center; /* Centers the numbers */
// flex: 1; /* Allows it to expand to fill the space */
// }
// }
} }
} }
.grafiek .grafiek
{ {
// background-color: blue; @include box-shadow;
@include border-radius;
padding: 1rem;
position: relative;
.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 .content
{ {
display: grid; display: grid;
@@ -181,7 +231,7 @@ body
&-rechts &-rechts
{ {
grid-column: 3; grid-column: 3;
// margin-right: 2rem; margin-right: 2rem;
#metingen #metingen
{ {
@@ -208,9 +258,86 @@ body
} }
} }
} }
.grid-column-2
{
@include box-shadow;
@include border-radius;
padding: 1rem;
margin: 3.25rem 1rem 1.25rem 1rem;
.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 */ /* Divider */
@@ -234,7 +361,7 @@ body
top: 50%; top: 50%;
transform: translate(-50%, -50%); transform: translate(-50%, -50%);
background: white; background: white;
padding: 20px; padding: 1.25rem;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
width: 30vw; width: 30vw;
height: auto; height: auto;
@@ -245,7 +372,7 @@ body
{ {
color: #aaa; color: #aaa;
float: right; float: right;
font-size: 28px; font-size: 1.75rem;
font-weight: bold; font-weight: bold;
&:hover, &:hover,

BIN
src/images/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@@ -4,22 +4,27 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title> <title>Document</title>
<link rel="stylesheet" href="./css/style.css"> <link rel="stylesheet" href="../src/css/style.css">
<script src="../script/main.js"></script> <script src="../src/js/main.js" defer></script>
<script src="../script/main.py" defer></script> <script src="../src/js/planten.class.js"></script>
</head> </head>
<body> <body>
<section class="mainContainer"> <section class="mainContainer">
<article>
<img src="../src/images/logo.png" class="goodgarden-logo">
</article>
<section class="mainBorder"> <section class="mainBorder">
<section class="content"> <section class="content">
<section class="kant-links"> <section class="kant-links">
<table id="planten"> <table id="planten">
<tr> <tr>
<td> <td>
<article> <a href="../src/kas_informatie.html">
<article class="article-1">
<img src="images/Icon awesome-apple-alt.png" alt=""> <img src="images/Icon awesome-apple-alt.png" alt="">
<h2>Tomaat</h2> <h2 class="plant-naam"></h2>
</article> </article>
</a>
</td> </td>
<td> <td>
<article> <article>
@@ -73,34 +78,25 @@
</td> </td>
</tr> </tr>
</table> </table>
<div class="formulier"> <div id="myModal" class="modal">
<div id="myModal" class="modal" style="display: none;"> <span class="close">&times;</span>
<h1>Plant Toevoegen</h1> <form action="http://localhost:3000/submit-form" method="post" onsubmit="return addplant()">
<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="plant_naam" id="plantNaam">
<input type="text" name="plantensoort" id="plantensoort"><br> <label for="plantNaam">Naam van de plant</label>
<label for="aanwezig">Aanwezig in de kas</label><br> <input type="text" name="plantensoort" id="plantensoort">
<select name="aanwezig_in_kas"> <label for="plantensoort">Soort van de plant</label>
<option value="ja">Ja</option>
<option value="nee">Nee</option>
</select><br>
<label for="ontvangenMeldingen">Meldingen ontvangen</label><br> <input type="radio" name="plant_geteelt" id="aanwezig" value="true">
<select name="ontvangen_meldingen"> <label for="aanwezig">Aanwezig</label>
<option value="ja">Ja</option>
<option value="nee">Nee</option> <input type="radio" name="plant_geteelt" id="afwezig" value="false">
</select><br> <label for="afwezig">Afwezig</label>
<input type="submit" value="Submit">
</form>
<section class="knop-container">
<br><button class="annulatie" type="button" onclick="closeOverlay()">Annuleren</button>
<button class="toevoeging" type="button" onclick="closeOverlay()">Toevoegen</button>
</section>
</form> <!-- Sluit de form-tag hier -->
</div>
</div> </div>
<div id="overlay" onclick="closeOverlay"></div> <div id="overlay" onclick="closeOverlay"></div>
</section> </section>
@@ -108,27 +104,36 @@
<section> <section>
</section> </section>
<section class="kant-rechts"> <section class="kant-rechts">
<section id="metingen"> <section id="sectie-1">
<article id="main-waardes"> <article class="parent-algemeen-overzicht">
<table> <article class="algemeen-overzicht">
<tr> <table class="table-informatie-kas">
<td> <tr class="tr-informatie-kas">
<p>Waardes</p> <td>Dagen tot Oogst</td>
</td> <td>12</td>
<td>
<p>Huidig</p>
</td>
<td>
<p>24u gemiddelde</p>
</td>
</tr> </tr>
<tr> <tr class="tr-informatie-kas">
<td> <td>Dagen in Kas</td>
<p>a</p> <td>2</td>
</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> </tr>
</table> </table>
</article> </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> </section>

115
src/js/main.js Normal file
View File

@@ -0,0 +1,115 @@
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();

32
src/js/planten.class.js Normal file
View File

@@ -0,0 +1,32 @@
dataHardObject = {
"id": 1,
"plantnaam": "Tomaat",
"plantensoort": "Groente",
"plantGeteelt": 1
}
// Nieuwe planten aanmaken in de table
// function hardcodeData(dataHardObject)
// {
// dataHardObject => "id"
// }
class Plant {
constructor(dataHardObject) {
this.id = dataHardObject.id;
this.plantNaam = dataHardObject.plantNaam;
this.plantensoort = dataHardObject.plantensoort;
this.plantGeteelt = dataHardObject.plantGeteelt;
}
htmlData(plantNaam) {
if (this.plantGeteelt)
{
const titel = document.querySelector(".plant-naam");
titel.textContent = this.plantNaam;
}
}
}
const tomaatPlant = new Plant(dataHardObject);
tomaatPlant.htmlData();

View File

@@ -1,25 +1,109 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <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> <title>Informatie Kas</title>
</head> </head>
<body> <body>
<section> <section class="mainContainer">
<article> <article>
<img src="../src/images/logo.png" class="goodgarden-logo">
</article>
<section class="mainBorder informatie-kas-main-container">
<article> <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> </article>
<article> <article class="grafiek">
<article> <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>
</article> </article>
</section> </section>
<section>
</section> </section>
</body> </body>
</html> </html>