Merge branch 'refactor'

This commit is contained in:
ferdzo
2024-10-10 00:42:43 +02:00
15 changed files with 163 additions and 38 deletions

2
.gitignore vendored
View File

@@ -4,4 +4,4 @@ db.sqlite3
demo.db
demo.db-shm
demo.db-wal
__pycache__/
__pycache__/

View File

@@ -0,0 +1,54 @@
import psycopg2
from psycopg2 import sql
import os
from dotenv import load_dotenv
# Load environment variables
load_dotenv()
# Define your database connection parameters
DATABASE_NAME = os.getenv('DB_NAME', 'example')
USER = os.getenv('DB_USER', 'postgres')
PASSWORD = os.getenv('DB_PASSWORD', 'coolermaster')
HOST = os.getenv('DB_HOST', '10.10.0.1')
PORT = os.getenv('DB_PORT', '5555')
def create_sensor_readings_table():
"""Create the sensor_readings table if it does not exist."""
try:
# Establish connection to the database
conn = psycopg2.connect(
dbname=DATABASE_NAME,
user=USER,
password=PASSWORD,
host=HOST,
port=PORT
)
with conn.cursor() as cursor:
# SQL command to create the sensor_readings table
create_table_query = """
CREATE TABLE IF NOT EXISTS sensor_readings (
time TIMESTAMPTZ NOT NULL,
device_name VARCHAR(255) NOT NULL, -- Use device_name as a string
metric VARCHAR(50) NOT NULL, -- Type of sensor
value DOUBLE PRECISION NOT NULL, -- The sensor's value
PRIMARY KEY (time, device_name, metric) -- Composite primary key
);
"""
cursor.execute(create_table_query)
print("Table 'sensor_readings' created or already exists.")
# Commit changes
conn.commit()
except Exception as e:
print(f"Error during database operations: {e}")
finally:
if conn:
conn.close()
print("Database connection closed.")
if __name__ == "__main__":
create_sensor_readings_table()

View File

@@ -1,48 +1,72 @@
from django import forms
from .models import Device, Sensor, SensorType
# Form for adding/editing devices
class DeviceForm(forms.ModelForm):
class Meta:
model = Device
fields = ['name', 'ip', 'protocol'] # Fields based on your Device model
widgets = {
'name': forms.TextInput(attrs={'class': 'form-control'}),
'ip': forms.TextInput(attrs={'class': 'form-control'}),
'protocol': forms.Select(attrs={'class': 'form-control'}),
}
# Form for adding a sensor with its type, including topic and endpoint for SensorType
class SensorWithTypeForm(forms.ModelForm):
type = forms.ModelChoiceField(
queryset=SensorType.objects.all(),
widget=forms.Select(attrs={'class': 'form-control'}),
label="Sensor Type"
# Optionally include sensors as choices in the form if relevant
sensors = forms.ModelMultipleChoiceField(
queryset=Sensor.objects.all(),
required=False,
widget=forms.CheckboxSelectMultiple,
label='Sensors'
)
class Meta:
model = Sensor
fields = ['device', 'type', 'enabled'] # Fields from your Sensor model
widgets = {
'device': forms.Select(attrs={'class': 'form-control'}),
'enabled': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
}
model = Device
fields = ['name', 'ip', 'protocol']
def __init__(self, *args, **kwargs):
# Optionally pass initial sensors for editing an existing device
if 'instance' in kwargs:
initial_sensors = kwargs['instance'].sensors.all() if kwargs['instance'] else None
initial = kwargs.get('initial', {})
initial['sensors'] = initial_sensors
kwargs['initial'] = initial
super(DeviceForm, self).__init__(*args, **kwargs)
def save(self, commit=True):
sensor = super().save(commit=False)
# Save the device instance
device = super(DeviceForm, self).save(commit=False)
if commit:
device.save()
self.save_m2m() # Ensure M2M save happens
return device
class SensorWithTypeForm(forms.ModelForm):
# Add fields for SensorType directly in the form
type_name = forms.CharField(max_length=50, label="Sensor Type Name")
unit = forms.CharField(max_length=20, label="Unit", required=False)
protocol = forms.ChoiceField(
choices=[('mqtt', 'MQTT'), ('http', 'HTTP')],
label="Protocol"
)
topic = forms.CharField(max_length=100, label="Topic", required=False)
endpoint = forms.CharField(max_length=100, label="Endpoint", required=False)
class Meta:
model = Sensor
fields = ['device', 'enabled']
def save(self, commit=True):
# Create or get the SensorType
try:
sensor_type = SensorType.objects.get(name=self.cleaned_data['type_name'])
except SensorType.DoesNotExist:
sensor_type = SensorType(
name=self.cleaned_data['type_name'],
unit=self.cleaned_data['unit'],
protocol=self.cleaned_data['protocol'],
topic=self.cleaned_data['topic'],
endpoint=self.cleaned_data['endpoint']
)
if commit:
sensor_type.save()
# Create Sensor with the SensorType found or created
sensor = super(SensorWithTypeForm, self).save(commit=False)
sensor.type = sensor_type
if commit:
sensor.save()
return sensor
# Form for creating or editing SensorType
class SensorTypeForm(forms.ModelForm):
class Meta:
model = SensorType
fields = ['name', 'unit', 'protocol', 'topic', 'endpoint'] # Fields from your SensorType model
widgets = {
'name': forms.TextInput(attrs={'class': 'form-control'}),
'unit': forms.TextInput(attrs={'class': 'form-control'}),
'protocol': forms.Select(attrs={'class': 'form-control'}),
'topic': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Optional for MQTT'}),
'endpoint': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Optional for HTTP'}),
}
return sensor

View File

@@ -0,0 +1,47 @@
# Generated by Django 4.2.5 on 2024-10-08 10:51
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('iotDashboard', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='SensorType',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=50, unique=True)),
('unit', models.CharField(max_length=20)),
('protocol', models.CharField(choices=[('mqtt', 'MQTT'), ('http', 'HTTP')], max_length=20)),
('topic', models.CharField(blank=True, max_length=100, null=True)),
('endpoint', models.CharField(blank=True, max_length=100, null=True)),
],
),
migrations.RemoveField(
model_name='device',
name='humidity',
),
migrations.RemoveField(
model_name='device',
name='temperature',
),
migrations.AlterField(
model_name='device',
name='protocol',
field=models.CharField(choices=[('mqtt', 'MQTT'), ('http', 'HTTP')], max_length=20),
),
migrations.CreateModel(
name='Sensor',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('enabled', models.BooleanField(default=True)),
('device', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='sensors', to='iotDashboard.device')),
('type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='iotDashboard.sensortype')),
],
),
]

View File

@@ -105,7 +105,7 @@ def insert_data(data, sensor_type):
except Exception as e:
print(f"Failed to insert data: {e}")
@periodic_task(crontab(minute='*/1'))
@periodi c_task(crontab(minute='*/1'))
def fetch_data_from_all_devices():
"""Fetch and insert data for all devices based on their protocol."""
devices = Device.objects.all()