Update models and db config
parent
ffc7a6254e
commit
9291563cd1
|
|
@ -2,6 +2,7 @@ from django.core.management.base import BaseCommand, CommandError
|
|||
from django.db import transaction, IntegrityError
|
||||
from django.utils import timezone
|
||||
from datavis.models import *
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
import datetime
|
||||
|
||||
|
|
@ -57,138 +58,173 @@ class Command(BaseCommand):
|
|||
"Temperature Site"
|
||||
]
|
||||
|
||||
author = User.objects.all()[0]
|
||||
|
||||
for group_type_name in group_types:
|
||||
group_type = GroupType()
|
||||
group_type.author = author
|
||||
group_type.name = group_type_name
|
||||
group_type.save()
|
||||
|
||||
def add_robot_hands_groups(self):
|
||||
group_types = GroupType.objects.all()
|
||||
|
||||
author = User.objects.all()[0]
|
||||
|
||||
"""
|
||||
Site: "Wisconsin Turkey"
|
||||
- [ ] Windrows: 2 Windrows
|
||||
- [ ] 10 temperature sites each
|
||||
"""
|
||||
robot_hands = Group()
|
||||
robot_hands.author = author
|
||||
robot_hands.name = "Robot Hands"
|
||||
robot_hands.save()
|
||||
group_type = Group2Type()
|
||||
group_type.author = author
|
||||
group_type.group = robot_hands
|
||||
group_type.type = group_types.get(name="Site")
|
||||
group_type.save()
|
||||
|
||||
incomplete_probes = Group()
|
||||
incomplete_probes.author = author
|
||||
incomplete_probes.name = "Incomplete Probes"
|
||||
incomplete_probes.save()
|
||||
group_type = Group2Type()
|
||||
group_type.author = author
|
||||
group_type.group = incomplete_probes
|
||||
group_type.type = group_types.get(name="Windrow")
|
||||
group_type.save()
|
||||
group_parent = GroupParent()
|
||||
group_parent.author = author
|
||||
group_parent.parent = robot_hands
|
||||
group_parent.child = incomplete_probes
|
||||
group_parent.save()
|
||||
|
||||
incomplete_base_stations = Group()
|
||||
incomplete_base_stations.author = author
|
||||
incomplete_base_stations.name = "Incomplete Base Stations"
|
||||
incomplete_base_stations.save()
|
||||
group_type = Group2Type()
|
||||
group_type.author = author
|
||||
group_type.group = incomplete_base_stations
|
||||
group_type.type = group_types.get(name="Windrow")
|
||||
group_type.save()
|
||||
group_parent = GroupParent()
|
||||
group_parent.author = author
|
||||
group_parent.parent = robot_hands
|
||||
group_parent.child = incomplete_base_stations
|
||||
group_parent.save()
|
||||
|
||||
complete_probes = Group()
|
||||
complete_probes.author = author
|
||||
complete_probes.name = "Probes Ready To Deploy"
|
||||
complete_probes.save()
|
||||
group_type = Group2Type()
|
||||
group_type.author = author
|
||||
group_type.group = complete_probes
|
||||
group_type.type = group_types.get(name="Windrow")
|
||||
group_type.save()
|
||||
group_parent = GroupParent()
|
||||
group_parent.author = author
|
||||
group_parent.parent = robot_hands
|
||||
group_parent.child = complete_probes
|
||||
group_parent.save()
|
||||
|
||||
complete_base_stations = Group()
|
||||
complete_base_stations.author = author
|
||||
complete_base_stations.name = "Base Stations Ready To Deploy"
|
||||
complete_base_stations.save()
|
||||
group_type = Group2Type()
|
||||
group_type.author = author
|
||||
group_type.group = complete_base_stations
|
||||
group_type.type = group_types.get(name="Windrow")
|
||||
group_type.save()
|
||||
group_parent = GroupParent()
|
||||
group_parent.author = author
|
||||
group_parent.parent = robot_hands
|
||||
group_parent.child = complete_base_stations
|
||||
group_parent.save()
|
||||
|
||||
def add_demo_site(self):
|
||||
group_types = GroupType.objects.all()
|
||||
author = User.objects.all()[0]
|
||||
|
||||
demo_site = Group()
|
||||
demo_site.author = author
|
||||
demo_site.name = "Wisconsin Turkey"
|
||||
demo_site.save()
|
||||
group_type = Group2Type()
|
||||
group_type.author = author
|
||||
group_type.group = demo_site
|
||||
group_type.type = group_types.get(name="Site")
|
||||
group_type.save()
|
||||
|
||||
windrow_1 = Group()
|
||||
windrow_1.author = author
|
||||
windrow_1.name = "Windrow 1"
|
||||
windrow_1.save()
|
||||
group_type = Group2Type()
|
||||
group_type.author = author
|
||||
group_type.group = windrow_1
|
||||
group_type.type = group_types.get(name="Windrow")
|
||||
group_type.save()
|
||||
group_parent = GroupParent()
|
||||
group_parent.author = author
|
||||
group_parent.parent = demo_site
|
||||
group_parent.child = windrow_1
|
||||
group_parent.save()
|
||||
|
||||
windrow_2 = Group()
|
||||
windrow_2.author = author
|
||||
windrow_2.name = "Windrow 2"
|
||||
windrow_2.save()
|
||||
group_type = Group2Type()
|
||||
group_type.author = author
|
||||
group_type.group = windrow_2
|
||||
group_type.type = group_types.get(name="Windrow")
|
||||
group_type.save()
|
||||
group_parent = GroupParent()
|
||||
group_parent.author = author
|
||||
group_parent.parent = demo_site
|
||||
group_parent.child = windrow_1
|
||||
group_parent.save()
|
||||
|
||||
for i in range(10):
|
||||
temperature_site = Group()
|
||||
temperature_site.author = author
|
||||
temperature_site.name = f"{windrow_1.name} - Site {i+1}"
|
||||
temperature_site.save()
|
||||
group_type = Group2Type()
|
||||
group_type.author = author
|
||||
group_type.group = temperature_site
|
||||
group_type.type = group_types.get(name="Temperature Site")
|
||||
group_type.save()
|
||||
group_parent = GroupParent()
|
||||
group_parent.author = author
|
||||
group_parent.parent = windrow_1
|
||||
group_parent.child = temperature_site
|
||||
group_parent.save()
|
||||
|
||||
for i in range(10):
|
||||
temperature_site = Group()
|
||||
temperature_site.author = author
|
||||
temperature_site.name = f"{windrow_2.name} - Site {i+1}"
|
||||
temperature_site.save()
|
||||
group_type = Group2Type()
|
||||
group_type.author = author
|
||||
group_type.group = temperature_site
|
||||
group_type.type = group_types.get(name="Temperature Site")
|
||||
group_type.save()
|
||||
group_parent = GroupParent()
|
||||
group_parent.author = author
|
||||
group_parent.parent = windrow_2
|
||||
group_parent.child = temperature_site
|
||||
group_parent.save()
|
||||
|
||||
def add_virtual_site(self):
|
||||
group_types = GroupType.objects.all()
|
||||
author = User.objects.all()[0]
|
||||
"""
|
||||
10 virtual nodes
|
||||
- [ ] 1 virtual base station
|
||||
|
|
@ -198,21 +234,26 @@ class Command(BaseCommand):
|
|||
- [ ] 2 weeks of sample data for all nodes
|
||||
"""
|
||||
virtual_site = Group()
|
||||
virtual_site.author = author
|
||||
virtual_site.name = "Virtual Site"
|
||||
virtual_site.save()
|
||||
group_type = Group2Type()
|
||||
group_type.author = author
|
||||
group_type.group = virtual_site
|
||||
group_type.type = group_types.get(name="Site")
|
||||
group_type.save()
|
||||
|
||||
windrow_1 = Group()
|
||||
windrow_1.author = author
|
||||
windrow_1.name = "Windrow 1"
|
||||
windrow_1.save()
|
||||
group_type = Group2Type()
|
||||
group_type.author = author
|
||||
group_type.group = windrow_1
|
||||
group_type.type = group_types.get(name="Windrow")
|
||||
group_type.save()
|
||||
group_parent = GroupParent()
|
||||
group_parent.author = author
|
||||
group_parent.parent = virtual_site
|
||||
group_parent.child = windrow_1
|
||||
group_parent.save()
|
||||
|
|
@ -220,23 +261,28 @@ class Command(BaseCommand):
|
|||
temperature_sites: list[Group] = []
|
||||
for i in range(10):
|
||||
temperature_site = Group()
|
||||
temperature_site.author = author
|
||||
temperature_site.name = f"{windrow_1.name} - Site {i+1}"
|
||||
temperature_site.save()
|
||||
temperature_sites.append(temperature_site)
|
||||
group_type = Group2Type()
|
||||
group_type.author = author
|
||||
group_type.group = temperature_site
|
||||
group_type.type = group_types.get(name="Temperature Site")
|
||||
group_type.save()
|
||||
group_parent = GroupParent()
|
||||
group_parent.author = author
|
||||
group_parent.parent = windrow_1
|
||||
group_parent.child = temperature_site
|
||||
group_parent.save()
|
||||
|
||||
virtual_base_station = Node()
|
||||
virtual_base_station.author = author
|
||||
virtual_base_station.friendly_name = "Virtual Base Station 1"
|
||||
virtual_base_station.hardware_id = "1"
|
||||
virtual_base_station.save()
|
||||
node_group = Node2Group()
|
||||
node_group.author = author
|
||||
node_group.node = virtual_base_station
|
||||
node_group.group = windrow_1
|
||||
node_group.save()
|
||||
|
|
@ -245,11 +291,13 @@ class Command(BaseCommand):
|
|||
created_nodes: list[Node] = []
|
||||
for i in range(NUM_VIRTUAL_NODES):
|
||||
virtual_node = Node()
|
||||
virtual_node.author = author
|
||||
virtual_node.friendly_name = f"Virtual Probe {i + 1}"
|
||||
virtual_node.save()
|
||||
created_nodes.append(virtual_node)
|
||||
|
||||
node_group = Node2Group()
|
||||
node_group.author = author
|
||||
node_group.node = virtual_node
|
||||
node_group.group = temperature_sites[i]
|
||||
node_group.save()
|
||||
|
|
|
|||
|
|
@ -1,19 +1,30 @@
|
|||
from django.db import models
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
class Node(models.Model):
|
||||
author = models.ForeignKey(to=User, on_delete=models.DO_NOTHING)
|
||||
creation_time = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
friendly_name = models.CharField(max_length = 255)
|
||||
hardware_id = models.CharField(max_length = 128)
|
||||
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.friendly_name} - {self.hardware_id}"
|
||||
|
||||
class Group(models.Model):
|
||||
author = models.ForeignKey(to=User, on_delete=models.DO_NOTHING)
|
||||
creation_time = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
name = models.CharField(max_length = 255)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class Node2Group(models.Model):
|
||||
author = models.ForeignKey(to=User, on_delete=models.DO_NOTHING)
|
||||
creation_time = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
node = models.ForeignKey(to=Node, on_delete=models.CASCADE)
|
||||
group = models.ForeignKey(to=Group, on_delete=models.CASCADE)
|
||||
|
||||
|
|
@ -24,6 +35,9 @@ class GroupType (models.Model):
|
|||
"""
|
||||
Application-level discriminating field for what a "group" is
|
||||
"""
|
||||
author = models.ForeignKey(to=User, on_delete=models.DO_NOTHING)
|
||||
creation_time = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
name = models.CharField(max_length = 255)
|
||||
|
||||
def __str__(self):
|
||||
|
|
@ -35,6 +49,9 @@ class GroupParent(models.Model):
|
|||
|
||||
TODO: Enforce child != parent
|
||||
"""
|
||||
author = models.ForeignKey(to=User, on_delete=models.DO_NOTHING)
|
||||
creation_time = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
child = models.ForeignKey(to=Group, on_delete=models.CASCADE, related_name='child_group')
|
||||
parent = models.ForeignKey(to=Group, on_delete=models.CASCADE, related_name='parent_group')
|
||||
|
||||
|
|
@ -42,6 +59,9 @@ class GroupParent(models.Model):
|
|||
return f"{self.child.name}<{self.parent.name}"
|
||||
|
||||
class Group2Type(models.Model):
|
||||
author = models.ForeignKey(to=User, on_delete=models.DO_NOTHING)
|
||||
creation_time = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
group = models.ForeignKey(to=Group, on_delete=models.CASCADE)
|
||||
type = models.ForeignKey(to=GroupType, on_delete=models.CASCADE)
|
||||
|
||||
|
|
@ -60,16 +80,19 @@ class Group2Type(models.Model):
|
|||
class Measurement(models.Model):
|
||||
source_node = models.ForeignKey(to=Node, on_delete=models.DO_NOTHING, related_name='measurement_source_node')
|
||||
collection_time = models.DateTimeField()
|
||||
server_received_time = models.DateTimeField()
|
||||
probe_temperature = models.FloatField()
|
||||
server_received_time = models.DateTimeField(auto_now_add=True)
|
||||
temperature_18_inch = models.FloatField()
|
||||
temperature_36_inch = models.FloatField()
|
||||
ambient_temperature = models.FloatField()
|
||||
# Onboard ESP32 temperature
|
||||
device_temperature = models.FloatField()
|
||||
barometric_pressure = models.FloatField()
|
||||
# Onboard temp, humidity. Probes:SHTxx, BS: BME280
|
||||
ambient_temperature = models.FloatField()
|
||||
relative_humidity = models.FloatField()
|
||||
# Base station only - BME280
|
||||
barometric_pressure = models.FloatField()
|
||||
accelerometer_x = models.FloatField()
|
||||
accelerometer_y = models.FloatField()
|
||||
accelerometer_z = models.FloatField()
|
||||
battery_charge_percent = models.FloatField()
|
||||
battery_voltage = models.FloatField()
|
||||
remaining_battery_capacity = models.FloatField()
|
||||
|
|
@ -85,3 +108,55 @@ class Measurement(models.Model):
|
|||
|
||||
class Meta:
|
||||
unique_together = (('source_node', 'collection_time'),)
|
||||
|
||||
class NodeRssiRecord(models.Model):
|
||||
device = models.ForeignKey(to=Node, on_delete=models.DO_NOTHING, related_name='rssi_source_node')
|
||||
collection_time = models.DateTimeField()
|
||||
server_received_time = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
# Neighbor we heard from
|
||||
neighbor = models.ForeignKey(to=Node, on_delete=models.DO_NOTHING)
|
||||
# Signal strength of neighbor from device's perspective
|
||||
rssi = models.IntegerField()
|
||||
|
||||
|
||||
class NodeFileManifest(models.Model):
|
||||
device = models.ForeignKey(to=Node, on_delete=models.DO_NOTHING)
|
||||
collection_time = models.DateTimeField()
|
||||
server_received_time = models.DateTimeField(auto_now_add=True)
|
||||
program_id = models.IntegerField()
|
||||
program_version = models.IntegerField()
|
||||
|
||||
class NodeReportedStatus(models.Model):
|
||||
"""
|
||||
Status reported by a Node
|
||||
"""
|
||||
""" Status 1 """
|
||||
device = models.ForeignKey(to=Node, on_delete=models.DO_NOTHING)
|
||||
collection_time = models.DateTimeField()
|
||||
server_received_time = models.DateTimeField(auto_now_add=True)
|
||||
measurement_interval_minutes = models.IntegerField()
|
||||
wake_window_length_minutes = models.IntegerField()
|
||||
# Default is things are aligned to midnight. This pushes it off that.
|
||||
offset_from_midnight_minutes = models.IntegerField()
|
||||
sleep_duration_minutes = models.IntegerField()
|
||||
|
||||
""" Status 2 """
|
||||
# Number of saved measurements on a node
|
||||
number_saved_measurements = models.IntegerField()
|
||||
|
||||
""" Other Things """
|
||||
when_time_was_last_updated = models.DateTimeField()
|
||||
|
||||
class NodeConfiguration(models.Model):
|
||||
"""
|
||||
Configuration to be applied to Node(s)
|
||||
"""
|
||||
author = models.ForeignKey(to=User, on_delete=models.DO_NOTHING)
|
||||
created_time = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
measurement_interval_minutes = models.IntegerField()
|
||||
wake_window_length_minutes = models.IntegerField()
|
||||
# Default is things are aligned to midnight. This pushes it off that.
|
||||
offset_from_midnight_minutes = models.IntegerField()
|
||||
sleep_duration_minutes = models.IntegerField()
|
||||
|
|
@ -100,27 +100,27 @@ DATABASES = {
|
|||
# 'ENGINE': 'django.db.backends.sqlite3',
|
||||
# 'NAME': BASE_DIR / 'db.sqlite3',
|
||||
#}
|
||||
'default': {
|
||||
"ENGINE": "django.db.backends.mysql",
|
||||
"OPTIONS": {
|
||||
#"read_default_file": BASE_DIR.as_posix() + "mysql.cnf",
|
||||
"read_default_file": "/Users/josh/Documents/ForgejoJed/RobotHands/frontend/mysql.cnf",
|
||||
},
|
||||
"HOST": "100.86.33.40",
|
||||
"PORT": 32768,
|
||||
}
|
||||
|
||||
# DigitalOcean test
|
||||
# 'default': {
|
||||
# "ENGINE": "django.db.backends.mysql",
|
||||
# "OPTIONS": {
|
||||
# #"read_default_file": BASE_DIR.as_posix() + "mysql.cnf",
|
||||
# "read_default_file": "/Users/josh/Documents/ForgejoJed/RobotHands/frontend/do_test.cnf",
|
||||
# "read_default_file": "/Users/josh/Documents/ForgejoJed/RobotHands/frontend/mysql.cnf",
|
||||
# },
|
||||
# "HOST": "db-mysql-nyc3-98489-do-user-14777372-0.g.db.ondigitalocean.com",
|
||||
# "PORT": 25060,
|
||||
# "HOST": "100.86.33.40",
|
||||
# "PORT": 32768,
|
||||
# }
|
||||
|
||||
# DigitalOcean test
|
||||
'default': {
|
||||
"ENGINE": "django.db.backends.mysql",
|
||||
"OPTIONS": {
|
||||
#"read_default_file": BASE_DIR.as_posix() + "mysql.cnf",
|
||||
"read_default_file": "/Users/josh/Documents/ForgejoJed/RobotHands/frontend/do_test.cnf",
|
||||
},
|
||||
"HOST": "rh-data-1-do-user-14777372-0.k.db.ondigitalocean.com",
|
||||
"PORT": 25060,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
CONN_MAX_AGE = 100
|
||||
|
|
|
|||
Loading…
Reference in New Issue