mirror of
https://github.com/ferdzo/iotDashboard.git
synced 2026-04-04 16:56:25 +00:00
Big update
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -0,0 +1,2 @@
|
||||
/iotDashboard/.env
|
||||
/.idea
|
||||
|
||||
BIN
db.sqlite3
BIN
db.sqlite3
Binary file not shown.
6
iotDashboard/apps.py
Normal file
6
iotDashboard/apps.py
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
from django.apps import AppConfig
|
||||
|
||||
class IotDashboardConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'iotDashboard'
|
||||
7
iotDashboard/forms.py
Normal file
7
iotDashboard/forms.py
Normal file
@@ -0,0 +1,7 @@
|
||||
from django import forms
|
||||
from .models import Device
|
||||
|
||||
class DeviceForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Device
|
||||
fields = ['name', 'ip', 'protocol', 'temperature', 'humidity']
|
||||
@@ -1,6 +1,6 @@
|
||||
import requests
|
||||
|
||||
devices = {"livingroom":"192.168.1.56"}
|
||||
devices = {"esp1":"192.168.244.131"}
|
||||
|
||||
def getTemp(device):
|
||||
r = requests.get("http://"+devices[device]+"/sensor/temperature")
|
||||
|
||||
@@ -1,17 +1,10 @@
|
||||
from django.db import models
|
||||
|
||||
class Device(models.Model):
|
||||
name = models.CharField(max_length=50)
|
||||
ip = models.CharField(max_length=20)
|
||||
protocol = models.CharField(max_length=20)
|
||||
temperature = models.BooleanField(default=False)
|
||||
humidity = models.BooleanField(default=False)
|
||||
brightness = models.BooleanField(default=False)
|
||||
|
||||
|
||||
|
||||
|
||||
class Measurement(models.Model):
|
||||
temperature = models.CharField(required=False,max_length=10)
|
||||
humidity = models.CharField(required=False,max_length=10)
|
||||
brightness = models.CharField(required=False,max_length=10)
|
||||
def __str__(self):
|
||||
return self.name
|
||||
@@ -11,6 +11,9 @@ https://docs.djangoproject.com/en/4.2/ref/settings/
|
||||
"""
|
||||
import environ
|
||||
from pathlib import Path
|
||||
import os
|
||||
from huey import SqliteHuey
|
||||
|
||||
|
||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||
@@ -24,6 +27,7 @@ environ.Env.read_env()
|
||||
|
||||
# SECURITY WARNING: keep the secret key used in production secret!
|
||||
SECRET_KEY = env('SECRET_KEY')
|
||||
CONNECTION_STRING = env('CONNECTION_STRING')
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = True
|
||||
@@ -40,6 +44,9 @@ INSTALLED_APPS = [
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
'iotDashboard',
|
||||
'huey.contrib.djhuey',
|
||||
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
@@ -57,7 +64,7 @@ ROOT_URLCONF = 'iotDashboard.urls'
|
||||
TEMPLATES = [
|
||||
{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'DIRS': [],
|
||||
'DIRS': [os.path.join(BASE_DIR, 'iotDashboard/templates')],
|
||||
'APP_DIRS': True,
|
||||
'OPTIONS': {
|
||||
'context_processors': [
|
||||
@@ -86,8 +93,8 @@ DATABASES = {
|
||||
"NAME" : "example",
|
||||
"USER": "postgres",
|
||||
"PASSWORD": env('PASSWORD'),
|
||||
"HOST": 'localhost',
|
||||
"PORT": '5432',
|
||||
"HOST": '10.10.0.1',
|
||||
"PORT": '5555',
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,3 +139,13 @@ STATIC_URL = 'static/'
|
||||
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field
|
||||
|
||||
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
||||
|
||||
|
||||
HUEY = {
|
||||
'huey_class': 'huey.SqliteHuey', # Or 'huey.RedisHuey' for Redis
|
||||
'filename': 'demo.db', # SQLite file for task storage
|
||||
'results': True,
|
||||
'store_none': False,
|
||||
'immediate': False,
|
||||
'utc': True,
|
||||
}
|
||||
37
iotDashboard/tasks.py
Normal file
37
iotDashboard/tasks.py
Normal file
@@ -0,0 +1,37 @@
|
||||
import psycopg2
|
||||
import requests
|
||||
from huey import crontab
|
||||
from huey.contrib.djhuey import periodic_task
|
||||
from datetime import datetime
|
||||
from django.conf import settings
|
||||
from .models import Device # Import your Device model
|
||||
|
||||
# Fetch data from the device using REST API
|
||||
def fetch_data_from_device(device):
|
||||
data = dict()
|
||||
data["time"] = datetime.now()
|
||||
data["device"] = device.name # Use device name
|
||||
r = requests.get(f"http://{device.ip}/sensor/tempreature")
|
||||
data["temperature"] = r.json()['value']
|
||||
r = requests.get(f"http://{device.ip}/sensor/humidity")
|
||||
data["humidity"] = r.json()['value']
|
||||
return (data["time"], data["device"], data["temperature"], data["humidity"])
|
||||
|
||||
# Insert data into the database
|
||||
def insert_data(device):
|
||||
data = fetch_data_from_device(device)
|
||||
with psycopg2.connect(settings.CONNECTION_STRING) as conn: # Use Django's connection string
|
||||
cursor = conn.cursor()
|
||||
insert_query = """
|
||||
INSERT INTO conditions (time, device, temperature, humidity)
|
||||
VALUES (%s, %s, %s, %s)
|
||||
"""
|
||||
cursor.execute(insert_query, data)
|
||||
conn.commit()
|
||||
|
||||
# Periodic task to fetch data from all devices every minute
|
||||
@periodic_task(crontab(minute='*/1'))
|
||||
def fetch_data_from_all_devices():
|
||||
devices = Device.objects.all() # Fetch all devices from the database
|
||||
for device in devices:
|
||||
insert_data(device)
|
||||
182
iotDashboard/templates/chart.html
Normal file
182
iotDashboard/templates/chart.html
Normal file
@@ -0,0 +1,182 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Conditions Chart with Chart.js</title>
|
||||
<!-- Bootstrap CSS -->
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
<style>
|
||||
.chart-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 400px;
|
||||
background-color: #f9f9f9;
|
||||
padding: 20px;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
#conditionsChart {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body class="bg-light">
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="#">IoT Dashboard</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{% url 'chart' %}">Chart</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{% url 'device_list' %}">Devices</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="navbar-nav">
|
||||
{% if user.is_authenticated %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{% url 'logout' %}">Logout</a>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{% url 'login' %}">Login</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="container mt-5">
|
||||
<h1 class="text-center mb-4">Temperature and Humidity Over Time</h1>
|
||||
|
||||
<!-- Device Selector Dropdown -->
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-4 offset-md-4">
|
||||
<select id="deviceSelector" class="form-select" onchange="fetchDeviceData()">
|
||||
{% for device in devices %}
|
||||
<option value="{{ device.name }}">{{ device.name }} ({{ device.ip }})</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Date Pickers for Time Window -->
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-6 offset-md-3 d-flex justify-content-between">
|
||||
<div>
|
||||
<label for="startDate" class="form-label">Start Date:</label>
|
||||
<input type="datetime-local" id="startDate" class="form-control" onchange="fetchDeviceData()">
|
||||
</div>
|
||||
<div>
|
||||
<label for="endDate" class="form-label">End Date:</label>
|
||||
<input type="datetime-local" id="endDate" class="form-control" onchange="fetchDeviceData()">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Chart Container -->
|
||||
<div class="row">
|
||||
<div class="col-md-8 offset-md-2">
|
||||
<div class="chart-container">
|
||||
<canvas id="conditionsChart"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var ctx = document.getElementById('conditionsChart').getContext('2d');
|
||||
var conditionsChart;
|
||||
|
||||
function fetchDeviceData() {
|
||||
var device = document.getElementById('deviceSelector').value;
|
||||
var startDate = document.getElementById('startDate').value;
|
||||
var endDate = document.getElementById('endDate').value;
|
||||
|
||||
fetch(`/fetch_device_data/?device=${device}&start_date=${startDate}&end_date=${endDate}`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (conditionsChart) {
|
||||
conditionsChart.destroy(); // Destroy the old chart
|
||||
}
|
||||
|
||||
conditionsChart = new Chart(ctx, {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: data.times,
|
||||
datasets: [
|
||||
{
|
||||
label: 'Temperature (°C)',
|
||||
data: data.temperatures,
|
||||
borderColor: 'red',
|
||||
fill: false,
|
||||
},
|
||||
{
|
||||
label: 'Humidity (%)',
|
||||
data: data.humidities,
|
||||
borderColor: 'blue',
|
||||
fill: false,
|
||||
}
|
||||
]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
scales: {
|
||||
x: {
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Time'
|
||||
},
|
||||
ticks: {
|
||||
autoSkip: true,
|
||||
maxRotation: 45,
|
||||
minRotation: 45,
|
||||
}
|
||||
},
|
||||
y: {
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Values'
|
||||
},
|
||||
beginAtZero: true
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
legend: {
|
||||
display: true,
|
||||
position: 'top',
|
||||
labels: {
|
||||
boxWidth: 20,
|
||||
padding: 20,
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
enabled: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Initial load for the default device and time range
|
||||
fetchDeviceData();
|
||||
</script>
|
||||
|
||||
<!-- Bootstrap JS and dependencies (Optional) -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
51
iotDashboard/templates/device_confirm_delete.html
Normal file
51
iotDashboard/templates/device_confirm_delete.html
Normal file
@@ -0,0 +1,51 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Delete Device</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body class="bg-light">
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="#">IoT Dashboard</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{% url 'chart' %}">Chart</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{% url 'device_list' %}">Devices</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="navbar-nav">
|
||||
{% if user.is_authenticated %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{% url 'logout' %}">Logout</a>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{% url 'login' %}">Login</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="container mt-5">
|
||||
<h1 class="text-center mb-4">Delete Device</h1>
|
||||
|
||||
<p class="text-center">Are you sure you want to delete the device "{{ device.name }}"?</p>
|
||||
|
||||
<form method="post" class="text-center">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="btn btn-danger">Delete</button>
|
||||
<a href="{% url 'device_list' %}" class="btn btn-secondary">Cancel</a>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
52
iotDashboard/templates/device_form.html
Normal file
52
iotDashboard/templates/device_form.html
Normal file
@@ -0,0 +1,52 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{% if form.instance.pk %}Edit{% else %}Add{% endif %} Device</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body class="bg-light">
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="#">IoT Dashboard</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{% url 'chart' %}">Chart</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{% url 'device_list' %}">Devices</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="navbar-nav">
|
||||
{% if user.is_authenticated %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{% url 'logout' %}">Logout</a>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{% url 'login' %}">Login</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="container mt-5">
|
||||
<h1 class="text-center mb-4">{% if form.instance.pk %}Edit{% else %}Add{% endif %} Device</h1>
|
||||
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
<div class="mb-3">
|
||||
{{ form.as_p }}
|
||||
</div>
|
||||
<button type="submit" class="btn btn-success">Save</button>
|
||||
<a href="{% url 'device_list' %}" class="btn btn-secondary">Cancel</a>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
73
iotDashboard/templates/device_list.html
Normal file
73
iotDashboard/templates/device_list.html
Normal file
@@ -0,0 +1,73 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Device Management</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body class="bg-light">
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="#">IoT Dashboard</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{% url 'chart' %}">Chart</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{% url 'device_list' %}">Devices</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="navbar-nav">
|
||||
{% if user.is_authenticated %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{% url 'logout' %}">Logout</a>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{% url 'login' %}">Login</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="container mt-5">
|
||||
<h1 class="text-center mb-4">Manage Devices</h1>
|
||||
|
||||
<a href="{% url 'add_device' %}" class="btn btn-primary mb-3">Add Device</a>
|
||||
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>IP Address</th>
|
||||
<th>Protocol</th>
|
||||
<th>Temperature Monitoring</th>
|
||||
<th>Humidity Monitoring</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for device in devices %}
|
||||
<tr>
|
||||
<td>{{ device.name }}</td>
|
||||
<td>{{ device.ip }}</td>
|
||||
<td>{{ device.protocol }}</td>
|
||||
<td>{{ device.temperature|yesno:"Yes,No" }}</td>
|
||||
<td>{{ device.humidity|yesno:"Yes,No" }}</td>
|
||||
<td>
|
||||
<a href="{% url 'edit_device' device.pk %}" class="btn btn-warning btn-sm">Edit</a>
|
||||
<a href="{% url 'delete_device' device.pk %}" class="btn btn-danger btn-sm">Delete</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -20,5 +20,13 @@ from iotDashboard import views
|
||||
|
||||
urlpatterns = [
|
||||
path('admin/', admin.site.urls),
|
||||
path('',views.index)
|
||||
path('',views.index),
|
||||
path('fetch_device_data/', views.fetch_device_data, name='fetch_device_data'),
|
||||
path('chart/',views.chart,name='chart'),
|
||||
path('devices/', views.device_list, name='device_list'),
|
||||
path('devices/add/', views.add_device, name='add_device'),
|
||||
path('devices/edit/<int:pk>/', views.edit_device, name='edit_device'),
|
||||
path('devices/delete/<int:pk>/', views.delete_device, name='delete_device'),
|
||||
path('login/', views.login_view, name='login'),
|
||||
path('logout/', views.logout_view, name='logout'),
|
||||
]
|
||||
|
||||
@@ -1,18 +1,86 @@
|
||||
from django.http import HttpResponse
|
||||
from django.http import HttpResponse, request, JsonResponse
|
||||
from django.db import connections
|
||||
|
||||
def my_custom_sql():
|
||||
with connections['data'].cursor() as cursor:
|
||||
# cursor.execute("SELECT * FROM conditions WHERE device='livingroom';"
|
||||
cursor.execute("SELECT * FROM conditions WHERE time > NOW() - INTERVAL '50 days' ;")
|
||||
row = cursor.fetchall()
|
||||
keys = ("time","device","tempreature","humidity")
|
||||
return row
|
||||
from django.shortcuts import render, redirect, get_object_or_404
|
||||
from .models import Device
|
||||
from .forms import DeviceForm
|
||||
|
||||
|
||||
|
||||
def fetch_device_data(request):
|
||||
device = request.GET.get('device', 'livingroom')
|
||||
start_date = request.GET.get('start_date')
|
||||
end_date = request.GET.get('end_date')
|
||||
|
||||
query = """
|
||||
SELECT time, temperature, humidity
|
||||
FROM conditions
|
||||
WHERE device = %s
|
||||
"""
|
||||
params = [device]
|
||||
|
||||
if start_date:
|
||||
query += " AND time >= %s"
|
||||
params.append(start_date)
|
||||
|
||||
if end_date:
|
||||
query += " AND time <= %s"
|
||||
params.append(end_date)
|
||||
|
||||
with connections["data"].cursor() as cursor:
|
||||
cursor.execute(query, params)
|
||||
rows = cursor.fetchall()
|
||||
|
||||
times = [row[0].strftime('%Y-%m-%d %H:%M:%S') for row in rows]
|
||||
temperatures = [row[1] for row in rows]
|
||||
humidities = [row[2] for row in rows]
|
||||
|
||||
return JsonResponse({
|
||||
'times': times,
|
||||
'temperatures': temperatures,
|
||||
'humidities': humidities,
|
||||
})
|
||||
def chart(request):
|
||||
devices = Device.objects.all()
|
||||
context = {'devices': devices}
|
||||
return render(request, 'chart.html', context)
|
||||
|
||||
def index(request):
|
||||
if request.user.is_authenticated:
|
||||
return HttpResponse(my_custom_sql())
|
||||
return HttpResponse("NOT AUTHENTICATED!!!")
|
||||
return HttpResponse(chart())
|
||||
return HttpResponse("NOT AUTHENTICATED!!!")
|
||||
def device_list(request):
|
||||
devices = Device.objects.all()
|
||||
return render(request, 'device_list.html', {'devices': devices})
|
||||
|
||||
def add_device(request):
|
||||
if request.method == 'POST':
|
||||
form = DeviceForm(request.POST)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
return redirect('device_list')
|
||||
else:
|
||||
form = DeviceForm()
|
||||
return render(request, 'device_form.html', {'form': form})
|
||||
|
||||
def edit_device(request, pk):
|
||||
device = get_object_or_404(Device, pk=pk)
|
||||
if request.method == 'POST':
|
||||
form = DeviceForm(request.POST, instance=device)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
return redirect('device_list')
|
||||
else:
|
||||
form = DeviceForm(instance=device)
|
||||
return render(request, 'device_form.html', {'form': form})
|
||||
|
||||
def delete_device(request, pk):
|
||||
device = get_object_or_404(Device, pk=pk)
|
||||
if request.method == 'POST':
|
||||
device.delete()
|
||||
return redirect('device_list')
|
||||
return render(request, 'device_confirm_delete.html', {'device': device})
|
||||
|
||||
def login_view():
|
||||
pass
|
||||
def logout_view():
|
||||
pass
|
||||
13
proba.py
13
proba.py
@@ -1,18 +1,23 @@
|
||||
import dotenv
|
||||
import psycopg2
|
||||
from psycopg2 import sql
|
||||
from datetime import datetime
|
||||
import requests
|
||||
from huey import SqliteHuey, crontab
|
||||
from dotenv import load_dotenv
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
# Initialize scheduler
|
||||
huey = SqliteHuey(filename='demo.db')
|
||||
|
||||
dotenv_path = Path("iotDashboard/.env")
|
||||
load_dotenv(dotenv_path=dotenv_path)
|
||||
CONNECTION = dotenv.dotenv_values(dotenv_path)["CONNECTION_STRING"]
|
||||
# Database connection
|
||||
CONNECTION = "postgres://postgres:postgres*@localhost:5432/example"
|
||||
conn = psycopg2.connect(CONNECTION)
|
||||
|
||||
# Devices
|
||||
devices = {"livingroom": "192.168.1.56","bedroom":"192.168.1.57"}
|
||||
devices = {"livingroom": "192.168.244.131"}
|
||||
|
||||
|
||||
# Func for fetching data from device using REST API
|
||||
@@ -20,7 +25,7 @@ def fetch_data_from_device(device):
|
||||
data = dict()
|
||||
data["time"] = datetime.now()
|
||||
data["device"] = device
|
||||
r = requests.get("http://" + devices[device] + "/sensor/temperature")
|
||||
r = requests.get("http://" + devices[device] + "/sensor/tempreature")
|
||||
data["temperature"] = r.json()['value']
|
||||
r = requests.get("http://" + devices[device] + "/sensor/humidity")
|
||||
data["humidity"] = r.json()['value']
|
||||
|
||||
Reference in New Issue
Block a user