diff --git a/apps/main/admin.py b/apps/main/admin.py
index 18496f8..28e3f16 100644
--- a/apps/main/admin.py
+++ b/apps/main/admin.py
@@ -1,10 +1,9 @@
from django.contrib import admin
-from .models import Device, DeviceType, Experiment, Campaign, Location, Radar
+from .models import Device, DeviceType, Experiment, Campaign, Location
# Register your models here.
admin.site.register(Campaign)
admin.site.register(Experiment)
admin.site.register(Device)
admin.site.register(DeviceType)
-admin.site.register(Location)
-admin.site.register(Radar)
\ No newline at end of file
+admin.site.register(Location)
\ No newline at end of file
diff --git a/apps/main/forms.py b/apps/main/forms.py
index c8276cb..7e611f0 100644
--- a/apps/main/forms.py
+++ b/apps/main/forms.py
@@ -1,9 +1,5 @@
from django import forms
from django.utils.safestring import mark_safe
-from datetime import datetime
-
-from apps.main.widgets import Filtering_ComboBox_Widget, Datepicker, HTMLrender,Filtering_ComboBox_Widget2
-
from .models import DeviceType, Device, Experiment, Campaign, Configuration, Location
@@ -38,6 +34,7 @@ class CampaignForm(forms.ModelForm):
exclude = ['']
class ExperimentForm(forms.ModelForm):
+
def __init__(self, *args, **kwargs):
super(ExperimentForm, self).__init__(*args, **kwargs)
self.fields['start_time'].widget = TimepickerWidget(self.fields['start_time'].widget.attrs)
@@ -67,8 +64,17 @@ class ConfigurationForm(forms.ModelForm):
class DeviceTypeForm(forms.Form):
device_type = forms.ChoiceField(choices=add_empty_choice(DeviceType.objects.all().order_by('name').values_list('id', 'name')))
+
+class UploadFileForm(forms.Form):
+
+ file = forms.FileField()
+
+class DownloadFileForm(forms.Form):
+
+ format = forms.ComboField()
+
class OperationForm(forms.Form):
- today = datetime.today()
+# today = datetime.today()
# -----Campaigns from this month------
- campaign = forms.ChoiceField(choices=Campaign.objects.filter(start_date__month=today.month).filter(start_date__year=today.year).order_by('-start_date').values_list('id', 'name'), label="Campaign")
+ campaign = forms.ChoiceField(choices=Campaign.objects.all().order_by('-start_date').values_list('id', 'name')[:5], label="Campaign")
\ No newline at end of file
diff --git a/apps/main/models.py b/apps/main/models.py
index ca347a7..ac9c19a 100644
--- a/apps/main/models.py
+++ b/apps/main/models.py
@@ -49,6 +49,18 @@ RADAR_STATES = (
)
# Create your models here.
+
+class Location(models.Model):
+
+ name = models.CharField(max_length = 30)
+ description = models.TextField(blank=True, null=True)
+
+ class Meta:
+ db_table = 'db_location'
+
+ def __unicode__(self):
+ return u'%s' % self.name
+
class DeviceType(models.Model):
name = models.CharField(max_length = 10, choices = DEV_TYPES, default = 'rc')
@@ -62,8 +74,8 @@ class DeviceType(models.Model):
class Device(models.Model):
- device_type = models.ForeignKey(DeviceType)
-# location = models.ForeignKey(Location)
+ device_type = models.ForeignKey(DeviceType, on_delete=models.CASCADE)
+ location = models.ForeignKey(Location, on_delete=models.CASCADE)
name = models.CharField(max_length=40, default='')
ip_address = models.GenericIPAddressField(protocol='IPv4', default='0.0.0.0')
@@ -98,24 +110,27 @@ class Campaign(models.Model):
def __unicode__(self):
return u'%s' % (self.name)
-class Radar(models.Model):
-
- name = models.CharField(max_length = 30)
- campaign = models.ForeignKey(Campaign)
- status = models.PositiveSmallIntegerField(default=0, choices=RADAR_STATES)
-
- class Meta:
- db_table = 'db_radar'
-
- def __unicode__(self):
- return u'%s' % self.name
+# class Radar(models.Model):
+#
+# # name = models.CharField(max_length = 30)
+# experiment = models.ForeignKey('Experiment', on_delete=models.CASCADE)
+# location = models.OneToOneField('Location', on_delete=models.CASCADE)
+# status = models.PositiveSmallIntegerField(default=0, choices=RADAR_STATES)
+#
+# class Meta:
+# db_table = 'db_radar'
+#
+# def __unicode__(self):
+# return u'%s' % self.location
class Experiment(models.Model):
template = models.BooleanField(default=False)
- radar = models.ForeignKey(Radar)
+ campaign = models.ForeignKey('Campaign', null=True, blank=True, on_delete=models.CASCADE)
+ location = models.ForeignKey('Location', null=True, blank=True, on_delete=models.CASCADE)
+
name = models.CharField(max_length=40, default='')
start_time = models.TimeField(default='00:00:00')
end_time = models.TimeField(default='23:59:59')
@@ -124,7 +139,7 @@ class Experiment(models.Model):
db_table = 'db_experiments'
def __unicode__(self):
- return u'[%s]: %s' % (self.radar.name, self.name)
+ return u'%s' % (self.name)
class Configuration(PolymorphicModel):
@@ -132,8 +147,8 @@ class Configuration(PolymorphicModel):
name = models.CharField(verbose_name="Configuration Name", max_length=40, default='')
- experiment = models.ForeignKey(Experiment)
- device = models.ForeignKey(Device)
+ experiment = models.ForeignKey('Experiment', null=True, blank=True, on_delete=models.CASCADE)
+ device = models.ForeignKey(Device, on_delete=models.CASCADE)
type = models.PositiveSmallIntegerField(default=0, choices=CONF_TYPES)
@@ -142,14 +157,94 @@ class Configuration(PolymorphicModel):
parameters = models.TextField(default='{}')
+ message = ""
+
class Meta:
db_table = 'db_configurations'
def __unicode__(self):
- return u'[%s - %s]: %s' % (self.experiment.campaign.name,
+ return u'[%s - %s]: %s' % (self.experiment.name,
self.experiment.name,
self.device.name)
+
+ def parms_to_dict(self):
+
+ parameters = {}
+
+ for key in self.__dict__.keys():
+ parameters[key] = getattr(self, key)
+
+ return parameters
+
+ def dict_to_parms(self, parameters):
+
+ if type(parameters) != type({}):
+ return
+
+ for key in parameters.keys():
+ setattr(self, key, parameters[key])
+
+ def export_to_file(self, format="json"):
+
+ import json
+ content_type = 'application/json'
+ filename = '%s.json' %self.name
+ content = json.dumps(self.params_to_dict())
+
+ if format == 'text':
+ content_type = 'text/plain'
+ filename = '%s.%s' %(self.name, self.device.device_type.name)
+ content = self.params_to_text()
+
+ if format == 'binary':
+ content_type = 'application/octet-stream'
+ filename = '%s.bin' %self.name
+ content = self.params_to_binary()
+
+ fields = {'content_type':content_type,
+ 'filename':filename,
+ 'content':content
+ }
+
+ return fields
+
+ def import_from_file(self, filename):
+
+ raise NotImplementedError, "This method should be implemented in each Configuration model"
+
+ return {}
+
+ def status_device(self):
+
+ raise NotImplementedError, "This method should be implemented in each Configuration model"
+
+ return None
+
+ def stop_device(self):
+
+ raise NotImplementedError, "This method should be implemented in each Configuration model"
+
+ return None
+
+ def start_device(self):
+
+ raise NotImplementedError, "This method should be implemented in each Configuration model"
+
+ return None
+
+ def write_device(self, parms):
+
+ raise NotImplementedError, "This method should be implemented in each Configuration model"
+
+ return None
+
+ def read_device(self):
+
+ raise NotImplementedError, "This method should be implemented in each Configuration model"
+
+ return None
+
def get_absolute_url(self):
return reverse('url_%s_conf' % self.device.device_type.name, args=[str(self.id)])
@@ -157,24 +252,22 @@ class Configuration(PolymorphicModel):
return reverse('url_edit_%s_conf' % self.device.device_type.name, args=[str(self.id)])
def get_absolute_url_import(self):
- return reverse('url_import_%s_conf' % self.device.device_type.name, args=[str(self.id)])
+ return reverse('url_import_dev_conf', args=[str(self.id)])
def get_absolute_url_export(self):
- return reverse('url_export_%s_conf' % self.device.device_type.name, args=[str(self.id)])
+ return reverse('url_export_dev_conf', args=[str(self.id)])
def get_absolute_url_write(self):
- return reverse('url_write_%s_conf' % self.device.device_type.name, args=[str(self.id)])
+ return reverse('url_write_dev_conf', args=[str(self.id)])
def get_absolute_url_read(self):
- return reverse('url_read_%s_conf' % self.device.device_type.name, args=[str(self.id)])
+ return reverse('url_read_dev_conf', args=[str(self.id)])
-class Location(models.Model):
-
- name = models.CharField(max_length = 30)
- description = models.TextField(blank=True, null=True)
-
- class Meta:
- db_table = 'db_location'
+ def get_absolute_url_start(self):
+ return reverse('url_start_dev_conf', args=[str(self.id)])
- def __unicode__(self):
- return u'%s' % self.name
\ No newline at end of file
+ def get_absolute_url_stop(self):
+ return reverse('url_stop_dev_conf', args=[str(self.id)])
+
+ def get_absolute_url_status(self):
+ return reverse('url_status_dev_conf', args=[str(self.id)])
\ No newline at end of file
diff --git a/apps/main/templates/dev_conf.html b/apps/main/templates/dev_conf.html
index 64783ae..ef2cde7 100644
--- a/apps/main/templates/dev_conf.html
+++ b/apps/main/templates/dev_conf.html
@@ -10,10 +10,25 @@
{% block content %}
+
+ Options
+
+
+
Status |
- {%if connected == True %} Connected {% else %} Disconnected {% endif %} |
+ {%if status %} {{status}} {% else %} Disconnected {% endif %} |
{% for key in dev_conf_keys %}
@@ -24,13 +39,6 @@
{% endfor %}
-
-
-
-
-
-
-
{% endblock %}
{% block sidebar%}
diff --git a/apps/main/templates/dev_conf_export.html b/apps/main/templates/dev_conf_export.html
new file mode 100644
index 0000000..029ea49
--- /dev/null
+++ b/apps/main/templates/dev_conf_export.html
@@ -0,0 +1 @@
+{% extends "dev_conf_edit.html" %}
\ No newline at end of file
diff --git a/apps/main/templates/dev_conf_import.html b/apps/main/templates/dev_conf_import.html
new file mode 100644
index 0000000..029ea49
--- /dev/null
+++ b/apps/main/templates/dev_conf_import.html
@@ -0,0 +1 @@
+{% extends "dev_conf_edit.html" %}
\ No newline at end of file
diff --git a/apps/main/templates/operation.html b/apps/main/templates/operation.html
index 57f0f63..e288a18 100644
--- a/apps/main/templates/operation.html
+++ b/apps/main/templates/operation.html
@@ -23,17 +23,17 @@
+
- {% for radar in radars %}
+ {% for location in locations %}
-
+
-
+ # |
{% for header in experiment_keys %}
{{ header|title }} |
{% endfor%}
+
{% for item in experiments %}
- {% for exs in item %}
-
-
- {% for key in experiment_keys %}
- {% if radar.name in exs.radar.name %}
- {{ exs|attr:key }} |
- {% endif %}
- {% endfor %}
- {% endfor %}
-
+ {% if location.name in item.location.name %}
+
+ {{ forloop.counter }} |
+ {% for key in experiment_keys %}
+ {{ item|value:key }} |
+ {% endfor %}
+
+ {% endif %}
{% endfor %}
diff --git a/apps/main/urls.py b/apps/main/urls.py
index 7b10d23..e5462a8 100644
--- a/apps/main/urls.py
+++ b/apps/main/urls.py
@@ -30,6 +30,14 @@ urlpatterns = (
url(r'^dev_conf/(?P
-?\d+)/$', 'apps.main.views.dev_conf', name='url_dev_conf'),
url(r'^dev_conf/(?P-?\d+)/edit/$', 'apps.main.views.dev_conf_edit', name='url_edit_dev_conf'),
url(r'^dev_conf/(?P-?\d+)/delete/$', 'apps.main.views.dev_conf_delete', name='url_delete_dev_conf'),
+
+ url(r'^dev_conf/(?P-?\d+)/write/$', 'apps.main.views.dev_conf_write', name='url_write_dev_conf'),
+ url(r'^dev_conf/(?P-?\d+)/read/$', 'apps.main.views.dev_conf_read', name='url_read_dev_conf'),
+ url(r'^dev_conf/(?P-?\d+)/import/$', 'apps.main.views.dev_conf_import', name='url_import_dev_conf'),
+ url(r'^dev_conf/(?P-?\d+)/export/$', 'apps.main.views.dev_conf_export', name='url_export_dev_conf'),
+ url(r'^dev_conf/(?P-?\d+)/start/$', 'apps.main.views.dev_conf_start', name='url_start_dev_conf'),
+ url(r'^dev_conf/(?P-?\d+)/stop/$', 'apps.main.views.dev_conf_stop', name='url_stop_dev_conf'),
+ url(r'^dev_conf/(?P-?\d+)/status/$', 'apps.main.views.dev_conf_status', name='url_status_dev_conf'),
url(r'^operation/$', 'apps.main.views.operation', name='url_operation'),
url(r'^operation/(?P-?\d+)/$', 'apps.main.views.operation', name='url_operation'),
diff --git a/apps/main/views.py b/apps/main/views.py
index 606e6c8..3e41dc4 100644
--- a/apps/main/views.py
+++ b/apps/main/views.py
@@ -1,9 +1,7 @@
from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
from django.contrib import messages
-from datetime import datetime
-
-from .forms import CampaignForm, ExperimentForm, DeviceForm, ConfigurationForm, LocationForm, OperationForm
+from .forms import CampaignForm, ExperimentForm, DeviceForm, ConfigurationForm, LocationForm, UploadFileForm, DownloadFileForm, OperationForm
from apps.cgs.forms import CGSConfigurationForm
from apps.jars.forms import JARSConfigurationForm
from apps.usrp.forms import USRPConfigurationForm
@@ -11,7 +9,7 @@ from apps.abs.forms import ABSConfigurationForm
from apps.rc.forms import RCConfigurationForm
from apps.dds.forms import DDSConfigurationForm
-from .models import Campaign, Experiment, Device, Configuration, Location, Radar
+from .models import Campaign, Experiment, Device, Configuration, Location
from apps.cgs.models import CGSConfiguration
from apps.jars.models import JARSConfiguration
from apps.usrp.models import USRPConfiguration
@@ -237,7 +235,8 @@ def campaigns(request):
def campaign(request, id_camp):
campaign = get_object_or_404(Campaign, pk=id_camp)
- #experiments = Experiment.objects.filter(campaign=campaign)
+ experiments = Experiment.objects.filter(campaign=campaign)
+
form = CampaignForm(instance=campaign)
kwargs = {}
@@ -247,7 +246,7 @@ def campaign(request, id_camp):
keys = ['id', 'name', 'start_time', 'end_time']
kwargs['experiment_keys'] = keys[1:]
- #kwargs['experiments'] = experiments.values(*keys)
+ kwargs['experiments'] = experiments.values(*keys)
kwargs['title'] = 'Campaign'
kwargs['suptitle'] = 'Details'
@@ -341,7 +340,7 @@ def experiment(request, id_exp):
kwargs = {}
- exp_keys = ['id', 'campaign', 'name', 'start_time', 'end_time']
+ exp_keys = ['id', 'campaign', 'location', 'name', 'start_time', 'end_time']
conf_keys = ['id', 'device__name', 'device__device_type', 'device__ip_address', 'device__port_address']
conf_labels = ['id', 'device__name', 'device_type', 'ip_address', 'port_address']
@@ -517,37 +516,203 @@ def dev_conf_edit(request, id_conf):
return render(request, 'dev_conf_edit.html', kwargs)
-def dev_conf_read(request, id_conf):
+def dev_conf_start(request, id_conf):
+
+ conf = get_object_or_404(Configuration, pk=id_conf)
+
+ DevConfModel = CONF_MODELS[conf.device.device_type.name]
+
+ conf = DevConfModel.objects.get(pk=id_conf)
+
+ if conf.start_device():
+ messages.success(request, conf.message)
+ else:
+ messages.error(request, conf.message)
+
+ return redirect(conf.get_absolute_url())
+
+def dev_conf_stop(request, id_conf):
conf = get_object_or_404(Configuration, pk=id_conf)
- messages.error(request, "Read View not implemented yet")
+ DevConfModel = CONF_MODELS[conf.device.device_type.name]
+
+ conf = DevConfModel.objects.get(pk=id_conf)
+
+ if conf.stop_device():
+ messages.success(request, conf.message)
+ else:
+ messages.error(request, conf.message)
+
+ return redirect(conf.get_absolute_url())
+
+def dev_conf_status(request, id_conf):
+
+ conf = get_object_or_404(Configuration, pk=id_conf)
+
+ DevConfModel = CONF_MODELS[conf.device.device_type.name]
+
+ conf = DevConfModel.objects.get(pk=id_conf)
+
+ if conf.status_device():
+ messages.success(request, conf.message)
+ else:
+ messages.error(request, conf.message)
- return redirect('url_dev_conf', id_conf=conf.id)
+ return redirect(conf.get_absolute_url())
+
def dev_conf_write(request, id_conf):
conf = get_object_or_404(Configuration, pk=id_conf)
- messages.error(request, "Write View not implemented yet")
+ DevConfModel = CONF_MODELS[conf.device.device_type.name]
+
+ conf = DevConfModel.objects.get(pk=id_conf)
+
+ answer = conf.write_device()
+
+ if answer:
+ messages.success(request, conf.message)
+
+ conf.pk = None
+ conf.id = None
+ conf.type = 1
+ conf.template = 0
+ conf.save()
+
+ else:
+ messages.error(request, conf.message)
- return redirect('url_dev_conf', id_conf=conf.id)
+ return redirect(conf.get_absolute_url())
+
+def dev_conf_read(request, id_conf):
+
+ conf = get_object_or_404(Configuration, pk=id_conf)
+
+ DevConfModel = CONF_MODELS[conf.device.device_type.name]
+ DevConfForm = CONF_FORMS[conf.device.device_type.name]
+
+ conf = DevConfModel.objects.get(pk=id_conf)
+
+ if request.method=='GET':
+
+ parms = conf.read_device()
+
+ if not parms:
+ messages.error(request, conf.message)
+ return redirect(conf.get_absolute_url())
+
+ form = DevConfForm(initial=parms, instance=conf)
+
+ if request.method=='POST':
+ form = DevConfForm(request.POST, instance=conf)
+
+ if form.is_valid():
+ dev_model = form.save(commit=False)
+
+ if dev_model.save():
+ return redirect(conf.get_absolute_url())
+
+ messages.error(request, "Parameters could not be saved")
+
+ kwargs = {}
+ kwargs['id_dev'] = conf.id
+ kwargs['form'] = form
+ kwargs['title'] = 'Device Configuration'
+ kwargs['suptitle'] = 'Parameters read from device'
+ kwargs['button'] = 'Save'
+
+ ###### SIDEBAR ######
+ kwargs.update(sidebar(conf))
+
+ return render(conf.get_absolute_url_edit())
def dev_conf_import(request, id_conf):
conf = get_object_or_404(Configuration, pk=id_conf)
- messages.error(request, "Import View not implemented yet")
+ DevConfModel = CONF_MODELS[conf.device.device_type.name]
+ DevConfForm = CONF_FORMS[conf.device.device_type.name]
- return redirect('url_dev_conf', id_conf=conf.id)
+ conf = DevConfModel.objects.get(pk=id_conf)
+
+ if request.method == 'GET':
+ file_form = UploadFileForm()
+
+ if request.method == 'POST':
+ file_form = UploadFileForm(request.POST, request.FILES)
+
+ if file_form.is_valid():
+
+ parms = conf.import_from_file(request.FILES['file'])
+
+ if parms:
+
+ messages.success(request, "Parameters imported from: '%s'." %request.FILES['file'].name)
+
+ form = DevConfForm(initial=parms, instance=conf)
+
+ kwargs = {}
+ kwargs['id_dev'] = conf.id
+ kwargs['form'] = form
+ kwargs['title'] = 'Device Configuration'
+ kwargs['suptitle'] = 'Parameters imported'
+ kwargs['button'] = 'Save'
+ kwargs['action'] = conf.get_absolute_url_edit()
+ kwargs['previous'] = conf.get_absolute_url()
+
+ ###### SIDEBAR ######
+ kwargs.update(sidebar(conf))
+
+ return render(request, '%s_conf_edit.html' %conf.device.device_type.name, kwargs)
+
+ messages.error(request, "Could not import parameters from file")
+
+ kwargs = {}
+ kwargs['id_dev'] = conf.id
+ kwargs['title'] = 'Device Configuration'
+ kwargs['form'] = file_form
+ kwargs['suptitle'] = 'Importing file'
+ kwargs['button'] = 'Import'
+
+ kwargs.update(sidebar(conf))
+
+ return render(request, 'dev_conf_import.html', kwargs)
def dev_conf_export(request, id_conf):
conf = get_object_or_404(Configuration, pk=id_conf)
- messages.error(request, "Export View not implemented yet")
+ DevConfModel = CONF_MODELS[conf.device.device_type.name]
+
+ conf = DevConfModel.objects.get(pk=id_conf)
+
+ if request.method == 'GET':
+ file_form = DownloadFileForm()
+
+ if request.method == 'POST':
+ file_form = DownloadFileForm(request.POST)
+
+ if file_form.is_valid():
+ fields = conf.export_to_file(format = file_form.format)
+
+ response = HttpResponse(content_type=fields['content_type'])
+ response['Content-Disposition'] = 'attachment; filename="%s"' %fields['filename']
+ response.write(fields['content'])
+
+ return response
+
+ messages.error(request, "Could not export parameters")
+
+ kwargs = {}
+ kwargs['id_dev'] = conf.id
+ kwargs['title'] = 'Device Configuration'
+ kwargs['form'] = file_form
+ kwargs['suptitle'] = 'Exporting file'
+ kwargs['button'] = 'Export'
- return redirect('url_dev_conf', id_conf=conf.id)
+ return render(request, 'dev_conf_export.html', kwargs)
def dev_conf_delete(request, id_conf):
@@ -592,25 +757,27 @@ def sidebar(conf):
def operation(request, id_camp=None):
- today = datetime.today()
-
- if id_camp==None:
- id_camp = Campaign.objects.filter(start_date__month=today.month).filter(start_date__year=today.year).order_by('-start_date')[0].id
+ if not id_camp:
+ campaigns = Campaign.objects.all().order_by('-start_date')
+
+ if not campaigns:
+ return render(request, 'operation.html', {})
+ id_camp = campaigns[0].id
+
+ campaign = get_object_or_404(Campaign, pk = id_camp)
+
if request.method=='GET':
- campaign = get_object_or_404(Campaign, pk = id_camp)
- campaigns = Campaign.objects.filter(start_date__month=today.month).filter(start_date__year=today.year).order_by('-start_date')
form = OperationForm(initial={'campaign': id_camp})
- if request.method=='POST':
- campaign = get_object_or_404(Campaign, pk=request.POST['campaign'])
- #id_camp = Campaign.objects.filter(start_date__month=today.month).filter(start_date__year=today.year).order_by('-start_date')[1].id
- form = OperationForm(request.POST, initial={'campaign':campaign.name})
+ if request.method=='POST':
+ form = OperationForm(request.POST, initial={'campaign':campaign.id})
+
if form.is_valid():
return redirect('url_operation', id_camp=campaign.id)
- radars = Radar.objects.filter(campaign = campaign)
- experiments = [Experiment.objects.filter(radar=radar) for radar in radars] #zip(radars, [Experiment.objects.filter(radar=radar) for radar in radars])
+ locations = Location.objects.filter(experiment__campaign = campaign)
+ experiments = Experiment.objects.filter(campaign=campaign)
kwargs = {}
#---Campaign
@@ -621,11 +788,11 @@ def operation(request, id_camp=None):
kwargs['experiment_keys'] = keys[1:]
kwargs['experiments'] = experiments
#---Radar
- kwargs['radars'] = radars
+ kwargs['locations'] = locations
#---Else
- kwargs['title'] = 'Operation'
+ kwargs['title'] = 'Campaign'
kwargs['suptitle'] = campaign.name
kwargs['form'] = form
- kwargs['button'] = '...'
+ kwargs['button'] = 'Apply'
return render(request, 'operation.html', kwargs)
\ No newline at end of file