summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sbhs/urls.py37
-rw-r--r--sbhs/views.py510
-rw-r--r--sbhs_raspi/requirements.txt6
-rw-r--r--sbhs_raspi/sbhs.py179
-rw-r--r--sbhs_raspi/sbhs_server.py299
-rw-r--r--sbhs_server/settings.py21
6 files changed, 493 insertions, 559 deletions
diff --git a/sbhs/urls.py b/sbhs/urls.py
index 07ad629..cfba27f 100644
--- a/sbhs/urls.py
+++ b/sbhs/urls.py
@@ -57,11 +57,42 @@ urlpatterns = [
################## Experiment urls #####################
url(r'^experiment/check_connection/$',views.check_connection,
name='experiment_check_connection'),
-
- url(r'^experiment/initiate/$',views.initiation,name='experiment_initiate'),
- url(r'^experiment/map_machines/$',views.map_sbhs_to_rpi,name='experiment_initiate'),
+ url(r'^experiment/initiate/$',views.initiation,
+ name='experiment_initiate'),
+ url(r'^experiment/client_version/?$', views.client_version,
+ name='experiment_client_version'),
+ url(r'^experiment/map_machines/$',views.map_sbhs_to_rpi,
+ name='experiment_initiate'),
+ url(r'^experiment/experiment/?$', views.experiment,
+ name='experiment_experiment'),
+ url(r'^experiment/logs/$',views.logs,name='experiment_logs'),
+ url(r'^experiment/logs/([0-9]+)/$',views.download_user_log,
+ name='experiment_logs'),
################## Moderator urls #####################
url(r'^moderator/$',views.moderator_dashboard,
name='moderator_dashboard'),
+ url(r'^moderator/all-bookings/$',views.all_bookings,
+ name='all_bookings'),
+ url(r'^moderator/all-boards/$',views.all_boards,
+ name='all_boards'),
+ url(r'^moderator/profile/(?P<mid>\d+)/$',views.profile,
+ name='profile'),
+ url(r'^moderator/log/(?P<mid>\d+)/$',views.download_log,
+ name='download_log'),
+ url(r'^moderator/logs_folder_index/?$',views.logs_folder_index,
+ name='logs_folder_index'),
+ url(r'^moderator/all-images/$',views.all_images,name='all_images'),
+ url(r'^moderator/test-boards/$',views.test_boards,name='test_boards'),
+ url(r'^moderator/update-mid/$',views.update_mid,name='update_mid'),
+ url(r'^moderator/fetch-logs/$',views.fetch_logs,name='fetch_logs'),
+ url(r'^moderator/fetch-logs/(?P<experiment_id>\d+)/$',views.download_file,
+ name='download_file'),
+
+ url(r'^moderator/turn-on-all-boards/$',views.turn_on_all_boards,
+ name='turn_on_all_boards'),
+ url(r'^moderator/turn-off-all-boards/$',views.turn_off_all_boards,
+ name='turn_off_all_boards'),
+ url(r'^moderator/book-all-suser-slots/$',views.book_all_suser_slots,
+ name='book_all_suser_slots'),
]
diff --git a/sbhs/views.py b/sbhs/views.py
index 37d307e..1d8c069 100644
--- a/sbhs/views.py
+++ b/sbhs/views.py
@@ -6,13 +6,13 @@ import random
import zipfile
import inspect
import pytz
-# import MySQLdb
import datetime
import requests
-import subprocess
+import subprocess, zipfile
# import serial
from textwrap import dedent
from time import gmtime, strftime
+import time
from datetime import datetime, timedelta, date
from django.urls import reverse
@@ -20,6 +20,7 @@ from django.conf import settings
from django.db import connection
from django.utils import timezone
from django.db.models import Count
+from django.contrib.auth.models import User
# import automatic_slot_booking
from django.contrib import messages
from django.template.loader import render_to_string
@@ -30,21 +31,24 @@ from django.shortcuts import render, redirect, get_object_or_404
from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
from django.http import HttpResponse, HttpResponseRedirect,\
Http404, HttpResponseServerError, JsonResponse
-from urllib.parse import urljoin
-from .models import Board, Experiment, Profile, Slot#, Webcam
-from .forms import UserLoginForm, UserRegistrationForm, SlotCreationForm
+from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
+
+
+from .models import Board, Experiment, Profile, Slot, UserBoard#, Webcam
+from .forms import (
+ UserLoginForm, UserRegistrationForm, SlotCreationForm, FilterLogsForm
+ )
from .send_emails import send_user_mail
from sbhs_server import credentials as credentials
from sbhs.decorators import email_verified
-
################# pages views #######################
-
def index(request, next_url=None):
if request.user.is_authenticated():
return render(request,'account/home.html')
return render(request,"pages/pages_index.html")
+
def about(req):
return render(req, "pages/about.html")
@@ -52,6 +56,7 @@ def about(req):
def info(request):
return render(request,"pages/info.html")
+
def downloads(req):
return redirect("http://sbhs.os-hardware.in/downloads")
@@ -59,19 +64,26 @@ def downloads(req):
def theory(req):
return render(req, "pages/theory.html")
+
def procedure(req):
return render(req, "pages/procedure.html")
+
def experiments(req):
return render(req, "pages/experiments.html")
+
def feedback(req):
return render(req, "pages/feedback.html")
#########Account Views ###########
@email_verified
def account_index(request):
- if request.user.is_authenticated():
+ user = request.user
+ if user.is_authenticated():
+ if not UserBoard.objects.filter(user=user).exists():
+ random_board = Board.objects.order_by('?').last()
+ UserBoard.objects.create(user=user, board=random_board)
return render(request,'account/home.html')
return render(request,'account/account_index.html',{
@@ -215,7 +227,7 @@ def update_email(request):
@email_verified
def slot_new(request):
user = request.user
- slot_history = Slot.objects.filter(user=user).order_by("start_time")
+ slot_history = Slot.objects.filter(user=user).order_by("-start_time")
context = {}
now = timezone.now()
if not request.user.is_authenticated():
@@ -261,47 +273,12 @@ def slot_new(request):
###################Experiment Views ######################
def check_connection(request):
- message = {"message":"TESTOK"}
- return JsonResponse(message, safe=True, status=200)
-
-@login_required
-def initial_login(request):
- """ Logs in an user for conducting the experiment on the specified
- board.
- Input: req:request object.
- Output: HttpResponse object.
- """
-
- username = request.POST.get("username")
- rpi_ip = ''
- try:
- assigned_mid = 2
- except Exception as e:
- return JsonResponse({
- "STATUS":400,
- "MESSAGE":{
- "IS_IP":"1",
- "DATA":"Invalid username"
- }
- })
- rpi_ip = '10.102.54.71'
- if rpi_ip is None:
- return JsonResponse({
- "STATUS":400,
- "MESSAGE":{
- "IS_IP":"1",
- "DATA":"Board is currently offline"
- }
- })
- return JsonResponse({
- "STATUS":200,
- "MESSAGE":{
- "IS_IP":"1",
- "DATA":rpi_ip
- }
- })
+ return HttpResponse("TESTOK")
+def client_version(request):
+ return HttpResponse(str(settings.CLIENT_VERSION))
+
@csrf_exempt
def initiation(request):
username = request.POST.get("username")
@@ -310,23 +287,45 @@ def initiation(request):
if user:
if user.is_active:
now = timezone.now()
- slots = Slot.objects.filter(user=user,
- start_time__gte=now,
- end_time__lt = now
- )
-
+ slots = Slot.objects.get_current_slots(user).order_by("id")
slot = slots.last()
- if slot:
- filename = ''
+ board = UserBoard.objects.get(user=user).board
+ check_status_path = "reset/{0}".format(board.usb_id)
+ check_status = connect_sbhs(board.raspi_path, check_status_path)
+ if check_status["status"] and slot:
+ filename = datetime.strftime(now, "%Y%b%d_%H_%M_%S.txt")
+ logdir = os.path.join(settings.EXPERIMENT_LOGS_DIR,
+ user.username
+ )
+ user_file = user.username + "/" + filename
+ if not os.path.exists(logdir):
+ os.makedirs(logdir)
+
+ if not Experiment.objects.filter(slot=slot,
+ log=user_file
+ ).exists():
+ Experiment.objects.create(slot=slot,
+ log=user_file
+ )
+
message = {
"STATUS":1,
- "MESSAGE": filename
- }
+ "MESSAGE": filename,
+ }
+ elif check_status["status"] and not slot:
+ message = {
+ "STATUS":0,
+ "MESSAGE":"Slot has ended. Please book the next slot."
+ }
+ elif not check_status["status"] and slot:
+ message = {
+ "STATUS":0,
+ "MESSAGE":"Slot is booked but Board is currently offline."
+ }
else:
message = {
"STATUS":0,
- "MESSAGE":"Slot has ended. Please book the next slot \
- to continue the experiment"
+ "MESSAGE":"Board is currently offline. Contact admin."
}
else:
message = {
@@ -339,7 +338,6 @@ def initiation(request):
"STATUS":0,
"MESSAGE":"Invalid username and password"
}
-
return JsonResponse(message, safe=True, status=200)
def map_sbhs_to_rpi(client_ip):
@@ -351,8 +349,7 @@ def map_sbhs_to_rpi(client_ip):
for r_pi in r_pis:
rpi_map = {}
rpi_map["rpi_ip"] = r_pi
- rpi_connect = connect_sbhs(r_pi, "get_machine_ids")
- mac_ids = json.loads(rpi_connect)
+ mac_ids = connect_sbhs(r_pi, "get_machine_ids")
board = Board()
board.save_board_details(r_pi, mac_ids)
rpi_map["mac_ids"] = [i['sbhs_mac_id'] for i in mac_ids]
@@ -361,17 +358,179 @@ def map_sbhs_to_rpi(client_ip):
rpi_map = {}
client_name = client_ip + ":1234"
rpi_map["rpi_ip"] = client_name
- rpi_connect = connect_sbhs(client_name, "get_machine_ids")
- mac_ids = json.loads(rpi_connect)
+ mac_ids = connect_sbhs(client_name, "get_machine_ids")
board = Board()
board.save_board_details(client_name, mac_ids)
+ rpi_map["mac_ids"] = [i['sbhs_mac_id'] for i in mac_ids]
+ map_machines.append(rpi_map)
+ return map_machines
def connect_sbhs(rpi_ip, experiment_url):
connect_rpi = requests.get("http://{0}/experiment/{1}".format(
rpi_ip, experiment_url
)
)
- return connect_rpi.text
+ data = json.loads(connect_rpi.text)
+ return data
+
+@csrf_exempt
+def experiment(request):
+ try:
+ username = request.POST.get("username")
+ server_start_ts = int(time.time() * 1000)
+ user = User.objects.get(username=username)
+ slot = Slot.objects.get_current_slots(user)\
+ .order_by("start_time").last()
+ board = UserBoard.objects.get(user=user).board
+ experiment = Experiment.objects.filter(slot=slot)
+ if experiment.exists():
+ experiment = experiment.first()
+ now = timezone.now()
+ endtime = slot.end_time
+ if endtime > now:
+ timeleft = int((endtime-now).seconds)
+ heat = max(min(int(request.POST.get("heat")), 100), 0)
+ fan = max(min(int(request.POST.get("fan")), 100), 0)
+ set_heat_url = "set_heat/{0}/{1}".format(board.usb_id, heat)
+ set_fan_url = "set_fan/{0}/{1}".format(board.usb_id, fan)
+ get_temp_url = "get_temp/{0}".format(board.usb_id)
+ set_heat = connect_sbhs(board.raspi_path, set_heat_url)
+ set_fan = connect_sbhs(board.raspi_path, set_fan_url)
+ get_temp = connect_sbhs(board.raspi_path,get_temp_url)
+ temp = get_temp["temp"]
+ log_data(board.mid, heat, fan, temp)
+
+ server_end_ts = int(time.time() * 1000)
+
+ STATUS = 1
+ MESSAGE = "%s %d %d %2.2f" % (request.POST.get("iteration"),
+ heat,
+ fan,
+ temp)
+ MESSAGE = "%s %s %d %d,%s,%d" % (MESSAGE,
+ request.POST.get("timestamp"),
+ server_start_ts,
+ server_end_ts,
+ request.POST.get("variables"),
+ timeleft)
+ experiment_log_path = os.path.join(
+ settings.EXPERIMENT_LOGS_DIR,
+ experiment.log
+ )
+ f = open(experiment_log_path, "a")
+ f.write(" ".join(MESSAGE.split(",")[:2]) + "\n")
+ f.close()
+ # Experiment.objects.create(slot=slot, log=experiment_log_path)
+ else:
+ STATUS = 0
+ MESSAGE = "Slot has ended. Please book the next slot to \
+ continue the experiment."
+ else:
+ STATUS = 0
+ MESSAGE = "You haven't booked this slot."
+
+ return HttpResponse(json.dumps({"STATUS": STATUS, "MESSAGE": MESSAGE}))
+ except Exception as e:
+ raise Exception
+ return HttpResponse(json.dumps({"STATUS": 0,
+ "MESSAGE": "Please Contact Admin"
+ }
+ )
+ )
+
+def log_data(mid, heat, fan, temp):
+
+ data = "{0} {1} {2} {3}\n".format(int(time.time()),str(heat),
+ str(fan), str(temp)
+ )
+ global_logfile = settings.SBHS_GLOBAL_LOG_DIR + "/" + str(mid) + ".log"
+ try:
+ with open(global_logfile, "a") as global_loghandler:
+ global_loghandler.write(data)
+ return True
+ except:
+ return False
+
+@login_required
+def logs(request):
+ user = request.user
+ context = {}
+ all_bookings = Slot.objects.filter(user__username=user)
+ all_booking_ids = [booking.id for booking in all_bookings]
+ experiment = Experiment.objects.select_related("slot").filter(slot_id__in=all_booking_ids)
+ for exp in experiment:
+ exp.logname = exp.log.split("/")[-1]
+ context['exp.logname'] = exp.logname
+ context['experiment'] = experiment
+ return render(request,'experiment/logs.html',context)
+
+@login_required
+def download_user_log(request, experiment_id):
+ user = request.user
+ experiment_data = Experiment.objects.get(slot__id=experiment_id)
+ f = open(os.path.join(settings.EXPERIMENT_LOGS_DIR, experiment_data.log),"r")
+ data = f.read()
+ print(data)
+ f.close()
+ return HttpResponse(data, content_type="text/text")
+
+
+# @csrf_exempt
+# def reset(req):
+# try:
+# from pi_server.settings import boards
+# user = req.user
+# if user.is_authenticated():
+# key = str(user.board.mid)
+# experiment = Experiment.objects.select_related().filter(id=boards[key]["experiment_id"])
+
+# if len(experiment) == 1 and user == experiment[0].booking.account:
+# experiment = experiment[0]
+# now = datetime.datetime.now()
+# endtime = experiment.booking.end_time()
+
+# boards[key]["board"].setHeat(0)
+# boards[key]["board"].setFan(100)
+
+# log_data(boards[key]["board"], key, experiment.id, 0, 100)
+# if endtime < now:
+# boards[key]["experiment_id"] = None
+# except:
+# pass
+
+# return HttpResponse("")
+
+# def log_data(sbhs, mid, experiment_id, heat=None, fan=None, temp=None):
+# if heat is None:
+# heat = sbhs.getHeat()
+# if fan is None:
+# fan = sbhs.getFan()
+# if temp is None:
+# temp = sbhs.getTemp()
+
+# data = "%d %s %s %s\n" % (int(time.time()), str(heat), str(fan), str(temp))
+# global_logfile = settings.SBHS_GLOBAL_LOG_DIR + "/" + str(mid) + ".log"
+# with open(global_logfile, "a") as global_loghandler:
+# global_loghandler.write(data)
+
+# def validate_log_file(req):
+# import hashlib
+# data = req.POST.get("data")
+# data = data.strip().split("\n")
+# clean_data = ""
+# for line in data:
+# columns = line.split(" ")
+# if len(columns) >= 6:
+# clean_data += (" ".join(columns[0:6]) + "\n")
+
+# checksum = hashlib.sha1(clean_data).hexdigest()
+
+# try:
+# e = Experiment.objects.get(checksum=checksum)
+# return HttpResponse("TRUE")
+# except:
+# return HttpResponse("FALSE")
+
################## Moderator Views ##########################
@@ -387,9 +546,224 @@ def moderator_dashboard(request):
if not is_moderator(user):
raise Http404("You are not allowed to see this page!")
else:
- all_boards = map_sbhs_to_rpi(request.META["SERVER_NAME"])
- context["all_active_boards"] = all_boards
- return render(request, 'dashboard/dashboard_index.html', context)
+ board_check = map_sbhs_to_rpi(request.META["SERVER_NAME"])
+ board = Board()
+ all_mac_ids = []
+ for machines in board_check:
+ all_mac_ids.extend(machines["mac_ids"])
+ board.switch_off_inactive_boards(all_mac_ids)
+ context["all_boards"] = Board.objects.all()
+ return render(request, 'dashboard/show_all_boards.html', context)
+
+@login_required
+def profile(request, mid):
+ user = request.user
+ context = {}
+ if not is_moderator(user):
+ raise Http404("You are not allowed to see this page.")
+ else:
+ try:
+ filename = settings.SBHS_GLOBAL_LOG_DIR + "/" + str(mid) + ".log"
+ print(filename)
+ except:
+ raise Http404("Log does not exist for this profile.")
+
+ delta_T = 1000
+ data = subprocess.check_output("tail -n {0} {1}".format(
+ delta_T, filename
+ ),
+ shell=True)
+ data = data.split("\n".encode())
+
+ heatcsv = ""
+ fancsv = ""
+ tempcsv = ""
+
+ plot = []
+ for t in range(len(data)):
+ line = data[t].decode("utf-8")
+ entry = line.strip().split(" ")
+ try:
+ plot.append([int(float(i)) for i in entry[0:-1] \
+ + [float(entry[-1])]])
+ heatcsv += "{0},{1}".format(t+1, entry[1])
+ fancsv += "{0},{1}".format(t+1,entry[2])
+ tempcsv += "{0},{1}".format(t+1, entry[3])
+ except:
+ continue
+
+ plot = zip(*plot)
+ context["mid"] = mid
+ context["delta_T"] = delta_T
+ context["heat"] = heatcsv
+ context["fan"] = fancsv
+ context["temp"] = tempcsv
+
+ return render(request,"dashboard/profile.html",context)
+
+@login_required
+def download_log(request, mid):
+ user = request.user
+ if not is_moderator(user):
+ raise Http404("You are not allowed to see this page.")
+ else:
+ try:
+ global_logfile = settings.SBHS_GLOBAL_LOG_DIR + "/" + str(mid) \
+ + ".log"
+ f = open(global_logfile,'r')
+ data = f.read()
+ f.close()
+ return HttpResponse(data, content_type='text/text')
+ except:
+ return HttpResponse("Requested log file does not exist")
+
+def zipdir(path,ziph):
+ for root, dirs, files in os.walk(path):
+ for file in files:
+ ziph.write(os.path.join(root,file))
+
+@login_required
+def logs_folder_index(request):
+ user = request.user
+ if not is_moderator(user):
+ raise Http404("You are not allowed to see this page.")
+ else:
+ if os.path.exists('Experiments.zip'):
+ os.remove('Experiments.zip')
+
+ with zipfile.ZipFile('Experiments.zip','w',zipfile.ZIP_DEFLATED) as zipf:
+ path = settings.BASE_DIR + '/experiments/'
+ zipdir(path,zipf)
+
+ with open('Experiments.zip','rb') as stream:
+ response = HttpResponse(stream,
+ content_type='application/force-download')
+ response['Content-Disposition'] = 'attachment; filename="{0}"'\
+ .format('Experiments.zip')
+ return response
+
+@login_required
+def all_bookings(request):
+ user = request.user
+ context = {}
+ if not is_moderator(user):
+ raise Http404("You are not allowed to see this page.")
+ else:
+ all_bookings = Slot.objects.all().order_by("-start_time")
+ paginator = Paginator(all_bookings, 20)
+ page = request.GET.get('page')
+ try:
+ slots = paginator.page(page)
+ except PageNotAnInteger:
+ slots = paginator.page(1)
+ except EmptyPage:
+ slots = paginator.page(paginator.num_pages)
+ context["slots"] = slots
+ return render(request,'dashboard/all_bookings.html', context)
+
+
+
+@login_required
+def all_boards(request):
+ user = request.user
+ if not is_moderator(user):
+ raise Http404("You are not allowed to see this page.")
+ else:
+ return render(request,'dashboard/all_boards.html')
+
+
+@login_required
+def all_images(request):
+ user = request.user
+ if not is_moderator(user):
+ raise Http404("You are not allowed to see this page.")
+ else:
+ return render(request,'dashboard/all_images.html')
+
+@login_required
+def test_boards(request):
+ user = request.user
+ now = timezone.now()
+ context = {}
+ if not is_moderator(user):
+ raise Http404("You are not allowed to see this page.")
+ else:
+ boards = Board.objects.filter(online=True)
+ slot_history = Slot.objects.all().order_by("-start_time")
+ context["boards"] = boards
+ context["slot_history"] = slot_history[0]
+ context["now"] = now
+ return render(request,'dashboard/test_boards.html',context)
+
+@login_required
+def update_mid(request):
+ user = request.user
+ if not is_moderator(user):
+ raise Http404("You are not allowed to see this page.")
+ else:
+ return render(request,'dashboard/update_mid.html')
+
+@login_required
+def fetch_logs(request):
+ user = request.user
+ context = {}
+ now = datetime.now()
+ if not is_moderator(user):
+ raise Http404("You are not allowed to see this page.")
+ else:
+ if request.method == 'POST':
+ form = FilterLogsForm(request.POST)
+ if form.is_valid():
+ start_date = form.data["start_time"]
+ end_date = form.data["end_time"]
+ if start_date and end_date:
+ ys,ms,ds = [int(x) for x in start_date.split('-')]
+ ye,me,de =[int(x) for x in end_date.split('-')]
+ slot = Slot.objects.filter(
+ start_time__date__gte=date(ys,ms,ds),
+ end_time__date__lte=date(ye,me,de)
+ )
+ experiment = Experiment.objects.filter(slot__in=slot)
+ context["experiments"] = experiment
+ else:
+ form=FilterLogsForm()
+ context['form']=form
+ return render(request,'dashboard/fetch_logs.html',context)
+
+def download_file(request, experiment_id):
+ experiment = Experiment.objects.get(id=experiment_id)
+ response = HttpResponse(content_type='application/text')
+ response['Content-Disposition'] = 'attachment; filename={0}'.format(
+ experiment.log
+ )
+ response.write(open("{0}/{1}".format(settings.MEDIA_ROOT,
+ experiment.log)
+ ).read())
+ return response
+
+@login_required
+def turn_on_all_boards(request):
+ user = request.user
+ if not is_moderator(user):
+ raise Http404("You are not allowed to see this page.")
+ else:
+ return HttpResponseRedirect(reverse('moderator_dashboard'))
+
+@login_required
+def turn_off_all_boards(request):
+ user = request.user
+ if not is_moderator(user):
+ raise Http404("You are not allowed to see this page.")
+ else:
+ return HttpResponseRedirect(reverse('moderator_dashboard'))
+
+@login_required
+def book_all_suser_slots(request):
+ user = request.user
+ if not is_moderator(user):
+ raise Http404("You are not allowed to see this page.")
+ else:
+ return HttpResponseRedirect(reverse('moderator_dashboard'))
# @login_required
diff --git a/sbhs_raspi/requirements.txt b/sbhs_raspi/requirements.txt
deleted file mode 100644
index 5f73360..0000000
--- a/sbhs_raspi/requirements.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-# Please run sbhs_communication_server files i.e. sbhs_server.py and sbhs.py in python 2 only.
-# This is because we could not figure out the working of pyserial with python 3.
-
-flask==1.0.2
-pyserial==3.4
-
diff --git a/sbhs_raspi/sbhs.py b/sbhs_raspi/sbhs.py
deleted file mode 100644
index 2f0c200..0000000
--- a/sbhs_raspi/sbhs.py
+++ /dev/null
@@ -1,179 +0,0 @@
-import serial
-import os
-import logging
-from time import localtime, strftime, sleep
-
-
-logging.basicConfig(filename="sbhserr.log",
- format='%(asctime)s --- %(message)s'
- )
-logger=logging.getLogger()
-logger.setLevel(logging.DEBUG)
-
-class SbhsServer(object):
- """ This is the Single Board Heater System class """
-
- def get_usb_devices(self):
- usb_ids = []
- for tty in os.listdir('/dev'):
- if tty.startswith('ttyUSB'):
- try:
- usb_ids.append(int(tty[6:]))
- except ValueError:
- logger.error("Could not get {0}".format(tty))
- return usb_ids
-
- def map_sbhs_to_usb(self, usb_devices):
- sbhs_map = []
- if usb_devices:
- for usb_id in usb_devices:
- sbhs = Sbhs(dev_id=usb_id)
- status = sbhs.connect_device()
- if status:
- board = sbhs.get_machine_id()
- logger.info("USB {0} is connected to SBHS machine id {1}"
- .format(usb_id, board)
- )
- sbhs_map.append({"usb_id": usb_id, "sbhs_mac_id": board})
- return sbhs_map
-
-
-class Sbhs(object):
-
- def __init__(self, dev_id):
-
- self.outgoing_machine_id = 252
- self.incoming_fan = 253
- self.incoming_heat = 254
- self.outgoing_temp = 255
- self.max_heat = 100
- self.max_fan = 100
- self.dev_id = dev_id
-
- def connect_device(self):
- """
- Open a serial connection via USB to the SBHS using USB Device Number
- """
- # check for valid device number
-
- usb_device_file = '/dev/ttyUSB{}'.format(self.dev_id)
- try:
- self.boardcon = serial.Serial(port=usb_device_file,
- baudrate=9600, bytesize=8,
- parity='N', stopbits=1,
- timeout=2
- )
- # org stopbits = 1
- status = True
- except Exception as e:
- status = False
- logger.error("Serial connection with {0} failed"
- .format(usb_device_file)
- )
- return status
-
- def get_machine_id(self):
- """ Gets machine id from the device """
- try:
- self.boardcon.flushInput()
- self._write(chr(self.outgoing_machine_id))
- sleep(0.5)
- machine_id = ord(self._read(1))
- self.machine_id = machine_id
- except Exception as e:
- machine_id = -1
- return int(machine_id)
-
- def set_machine_heat(self, val):
- """ Sets the heat, checks if value is valid i.e. within range.
- Input: self object, val
- Output: Error message if heat cannot be set.
- """
- if val > self.max_heat or val < 0:
- logger.error("Machine ID {0} tried setting heat {1}%".format())
- return False
-
- try:
- self._write(chr(self.incoming_heat))
- sleep(0.5)
- self._write(chr(val))
- return True
- except:
- print("Error: cannot set heat for machine \
- id {}".format(self.machine_id))
- self.log('cannot set heat for machine id \
- %d' % self.machine_id, 'ERROR')
- return False
-
- def set_machine_fan(self, val):
- """ Sets the fan speed, checks if value is valid i.e. within range.
- Input: self object, val
- Output: Error message if fan cannot be set.
- """
- if val > self.max_fan or val < 0:
- return False
- try:
- self._write(chr(self.incoming_fan))
- sleep(0.5)
- self._write(chr(val))
- return True
- except:
- return True
-
- def get_machine_temp(self):
- """ Gets the temperature from the machine.
- """
- try:
- self.boardcon.flushInput()
- self._write(chr(self.outgoing_temp))
- temp = ord(self._read(1)) + (0.1 * ord(self._read(1)))
- return temp
- except:
- print("Error: cannot read temperature from machine id \
- {}".format(self.machine_id))
- self.log('cannot read temperature from machine id %d' \
- % self.machine_id, 'ERROR')
- return 0.0
-
- def disconnect(self):
- """ Reset the board fan and heat values and close the USB connection """
- try:
- self.boardcon.close()
- self.boardcon = False
- self.status = 0
- return True
- except:
- print('Error: cannot close connection to the machine')
- self.log('cannot close connection to the machine', 'ERROR')
- return False
-
- def reset_board(self):
- return self.set_machine_heat(0) and self.set_machine_fan(100)
-
- def _read(self, size):
- try:
- data = self.boardcon.read(size)
- return data
- except Exception as e:
- raise
-
- def _write(self, data):
- try:
- self.boardcon.write(data)
- return True
- except Exception as e:
- raise
-
- def log(self, msg, level):
- try:
- errfile = open(LOG_FILE, 'a') # open error log file in append mode
- if not errfile:
- return
- log_msg = '%s %s %s\n' %(level, strftime('%d:%m:%Y %H:%M:%S', \
- localtime()), msg)
-
- errfile.write(log_msg)
- errfile.close()
- return
- except:
- return
diff --git a/sbhs_raspi/sbhs_server.py b/sbhs_raspi/sbhs_server.py
deleted file mode 100644
index 109c18d..0000000
--- a/sbhs_raspi/sbhs_server.py
+++ /dev/null
@@ -1,299 +0,0 @@
-from flask import (Flask, flash, redirect, render_template, request, url_for,
- Response, jsonify)
-from logging.config import dictConfig
-from sbhs import SbhsServer, Sbhs
-
-# dictConfig({
-# 'version': 1,
-# 'formatters': {'default': {
-# 'format': '[%(asctime)s] %(levelname)s in %(module)s: %(message)s',
-# }},
-# 'handlers': {'file': {
-# 'class': 'logging.FileHandler',
-# 'formatter': 'default',
-# 'filename': 'error.log',
-# }},
-
-# 'root': {
-# 'level': 'DEBUG',
-# 'handlers': ['file']
-# }
-# })
-
-app = Flask(__name__)
-
-@app.route('/experiment/check_connection')
-def check_connection():
- return Response("TESTOK")
-
-@app.route('/experiment/client_version')
-def client_version():
- return Response("3")
-
-@app.route('/experiment/get_machine_ids')
-def get_machine_ids():
- sbhs_server = SbhsServer()
- all_mac_ids = sbhs_server.map_sbhs_to_usb(sbhs_server.get_usb_devices())
- return jsonify(all_mac_ids)
-
-@app.route('/experiment/set_fan/<int:dev_num>/<int:fan_speed>')
-def set_fan(dev_num, fan_speed):
- sbhs_server = Sbhs(dev_num)
- connect = sbhs_server.connect_device()
- message = "Could not set fan speed"
- if connect:
- status = sbhs_server.set_machine_fan(fan_speed)
- if status:
- message = "Set fan speed at {}%".format(fan_speed)
- return Response(message)
-
-@app.route('/experiment/set_heat/<int:dev_num>/<int:heat>')
-def set_heat(dev_num, heat):
- sbhs_server = Sbhs(dev_num)
- connect = sbhs_server.connect_device()
- message = "Could not set heat"
- if connect:
- status = sbhs_server.set_machine_heat(heat)
- if status:
- message = "Set heat at {}%".format(heat)
- return Response(message)
-
-@app.route('/experiment/get_temp/<int:dev_num>')
-def get_temp(dev_num):
- sbhs_server = Sbhs(dev_num)
- connect = sbhs_server.connect_device()
- message = "Could not fetch temperature"
- if connect:
- status = sbhs_server.get_machine_temp()
- return jsonify({"temp": status})
- return Response(message)
-
-@app.route('/experiment/reset/<int:dev_num>')
-def reset(dev_num):
- sbhs_server = Sbhs(dev_num)
- connect = sbhs_server.connect_device()
- message = "Reset Failed"
- if connect:
- status = sbhs_server.reset_board()
- message = "Reset Successful"
- return Response(message)
-
-@app.route('/experiment/disconnect/<int:dev_num>')
-def disconnect(dev_num):
- sbhs_server = Sbhs(dev_num)
- connect = sbhs_server.connect_device()
- message = "Disconnect Failed"
- if connect:
- status = sbhs_server.disconnect_machine()
- message = "Diconnected"
- return Response(message)
-
-# @app.route('/experiment/shutdown/<int:dev_num>')
-# def shutdown(dev_num):
-# sbhs_server = SbhsServer()
-# connect = sbhs_server.connect_device(dev_num)
-# message = "Disconnect Failed"
-# if connect:
-# status = sbhs_server.shutdown_machine()
-# message = "Killed"
-# return Response(message)
-
-
-# @csrf_exempt
-# def initiation(req):
-# username = req.POST.get("username")
-# password = req.POST.get("password")
-# user = authenticate(username=username, password=password)
-# if user is not None:
-# if user.is_active:
-# user1 = Account.objects.select_related().filter(id=user.id)
-# user1 = user1[0]
-# user_board = user1.board
-
-# #allows admin to access the temporary offline devices but prohibits the users to do so
-# if user_board.online and (not user_board.temp_offline \
-# or user1.is_admin):
-# slots = Slot.slots_now()
-# slot_ids = [s.id for s in slots]
-# now = datetime.datetime.now()
-# bookings = user.booking_set.filter(booking_date__year=now.year,
-# booking_date__month=now.month,
-# booking_date__day=now.day,
-# slot_id__in=slot_ids)\
-# .select_related("slot")
-# try:
-# cur_booking = bookings[0]
-# active_slot = cur_booking.slot
-# except:
-# cur_booking = None
-# active_slot = None
-
-# if active_slot is not None:
-# endtime = cur_booking.end_time()
-# if now < endtime:
-# filename = datetime.datetime.strftime(now, \
-# "%Y%b%d_%H_%M_%S.txt")
-# logdir = os.path.join(settings.EXPERIMENT_LOGS_DIR, \
-# user.username)
-# if not os.path.exists(logdir):
-# os.makedirs(logdir)
-
-# f = open(os.path.join(logdir, filename), "a")
-# f.close()
-
-# LOGIN(req, user)
-
-# e = Experiment()
-# e.booking=cur_booking
-# e.log=user.username + "/" + filename
-# e.save()
-
-# key = str(user_board.mid)
-
-# settings.boards[key]["experiment_id"] = e.id
-
-# reset(req)
-
-# STATUS = 1
-# MESSAGE = filename
-# else:
-# reset(req)
-# STATUS = 0
-# MESSAGE = "Slot has ended. Please book the next slot \
-# to continue the experiment."
-# else:
-# STATUS = 0
-# MESSAGE = "You haven't booked this slot."
-# else:
-# STATUS = 0
-# MESSAGE = "Your SBHS is offline. Please contact the Vlabs \
-# team."
-# else:
-# STATUS = 0
-# MESSAGE = "Your account is not activated yet. Please check your \
-# email for activation link."
-# else:
-# STATUS = 0
-# MESSAGE = "Invalid username or password"
-
-# return HttpResponse(json.dumps({"STATUS": STATUS, "MESSAGE": MESSAGE}))
-
-# @login_required(redirect_field_name=None)
-# @csrf_exempt
-# def experiment(req):
-# try:
-# server_start_ts = int(time.time() * 1000)
-# from pi_server.settings import boards
-# user = req.user
-# key = str(user.board.mid)
-# experiment = Experiment.objects.select_related()\
-# .filter(id=boards[key]["experiment_id"])
-
-# if len(experiment) == 1 and user.id == experiment[0].booking.account.id and experiment[0].booking.trashed_at == None:
-# experiment = experiment[0]
-# now = datetime.datetime.now()
-# endtime = experiment.booking.end_time()
-# if endtime > now:
-# timeleft = int((endtime-now).seconds)
-# heat = max(min(int(req.POST.get("heat")), 100), 0)
-# fan = max(min(int(req.POST.get("fan")), 100), 0)
-
-# boards[key]["board"].setHeat(heat)
-# boards[key]["board"].setFan(fan)
-# temperature = boards[key]["board"].getTemp()
-# log_data(boards[key]["board"], key, experiment.id, heat=heat, fan=fan, temp=temperature)
-
-# server_end_ts = int(time.time() * 1000)
-
-# STATUS = 1
-# MESSAGE = "%s %d %d %2.2f" % (req.POST.get("iteration"),
-# heat,
-# fan,
-# temperature)
-# MESSAGE = "%s %s %d %d,%s,%d" % (MESSAGE,
-# req.POST.get("timestamp"),
-# server_start_ts,
-# server_end_ts,
-# req.POST.get("variables"), timeleft)
-
-# f = open(os.path.join(settings.EXPERIMENT_LOGS_DIR, experiment.log), "a")
-# f.write(" ".join(MESSAGE.split(",")[:2]) + "\n")
-# f.close()
-# else:
-# # boards[key]["board"].setHeat(0)
-# # boards[key]["board"].setFan(100)
-# # log_data(boards[key]["board"], key)
-# reset(req)
-
-# STATUS = 0
-# MESSAGE = "Slot has ended. Please book the next slot to continue the experiment."
-
-# reset(req)
-# boards[key]["experiment_id"] = None
-# else:
-# STATUS = 0
-# MESSAGE = "You haven't booked this slot."
-
-# return HttpResponse(json.dumps({"STATUS": STATUS, "MESSAGE": MESSAGE}))
-# except Exception:
-# return HttpResponse(json.dumps({"STATUS": 0, "MESSAGE": "Invalid input. Perhaps the slot has ended. Please book the next slot to continue the experiment."}))
-
-# @csrf_exempt
-# def reset(req):
-# try:
-# from pi_server.settings import boards
-# user = req.user
-# if user.is_authenticated():
-# key = str(user.board.mid)
-# experiment = Experiment.objects.select_related().filter(id=boards[key]["experiment_id"])
-
-# if len(experiment) == 1 and user == experiment[0].booking.account:
-# experiment = experiment[0]
-# now = datetime.datetime.now()
-# endtime = experiment.booking.end_time()
-
-# boards[key]["board"].setHeat(0)
-# boards[key]["board"].setFan(100)
-
-# log_data(boards[key]["board"], key, experiment.id, 0, 100)
-# if endtime < now:
-# boards[key]["experiment_id"] = None
-# except:
-# pass
-
-# return HttpResponse("")
-
-# def log_data(sbhs, mid, experiment_id, heat=None, fan=None, temp=None):
-# if heat is None:
-# heat = sbhs.getHeat()
-# if fan is None:
-# fan = sbhs.getFan()
-# if temp is None:
-# temp = sbhs.getTemp()
-
-# data = "%d %s %s %s\n" % (int(time.time()), str(heat), str(fan), str(temp))
-# global_logfile = settings.SBHS_GLOBAL_LOG_DIR + "/" + str(mid) + ".log"
-# with open(global_logfile, "a") as global_loghandler:
-# global_loghandler.write(data)
-
-# def validate_log_file(req):
-# import hashlib
-# data = req.POST.get("data")
-# data = data.strip().split("\n")
-# clean_data = ""
-# for line in data:
-# columns = line.split(" ")
-# if len(columns) >= 6:
-# clean_data += (" ".join(columns[0:6]) + "\n")
-
-# checksum = hashlib.sha1(clean_data).hexdigest()
-
-# try:
-# e = Experiment.objects.get(checksum=checksum)
-# return HttpResponse("TRUE")
-# except:
-# return HttpResponse("FALSE")
-
-
-if __name__ == "__main__":
- app.run(host="127.0.0.1", port=1234) \ No newline at end of file
diff --git a/sbhs_server/settings.py b/sbhs_server/settings.py
index 3b2a68d..b0930fa 100644
--- a/sbhs_server/settings.py
+++ b/sbhs_server/settings.py
@@ -130,7 +130,7 @@ STATIC_URL = '/static/'
SLOT_DURATION = 55
MEDIA_URL = '/media/'
-MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
+MEDIA_ROOT = os.path.join(BASE_DIR, 'experiments/')
EMAIL_USE_TLS = True
@@ -172,7 +172,20 @@ IS_DEVELOPMENT=False
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
-RASP_PI_IP = []
-# enter comma separated raspberry pi IPs here
+RASP_PI_IPS = []
+# RASP_PI_IPS = ['10.101.202.74:1234']
+# enter comma separated raspberry pi IPs here with ports
+# for e.g 127.0.0.1:1234
-RASPI_SBHS_CONNECTION = True if RASP_PI_IP else False
+CLIENT_VERSION = 3
+#Client version supported by Django server
+
+EXPERIMENT_LOGS_DIR = os.path.join(BASE_DIR, 'experiments')
+#Path for user experiment folders on Django server.
+
+SBHS_GLOBAL_LOG_DIR = os.path.join(BASE_DIR, 'log')
+# Path for sbhs global log directory on Django server.
+
+SESSION_EXPIRE_AT_BROWSER_CLOSE = True
+CSRF_COOKIE_NAME = "pfesgbxra"
+SESSION_COOKIE_NAME = "frffvbaVq"