Skip to content

Commit

Permalink
wip for #37
Browse files Browse the repository at this point in the history
  • Loading branch information
Rob Baynes committed Jun 19, 2018
1 parent 57f64b0 commit e922156
Show file tree
Hide file tree
Showing 15 changed files with 158 additions and 12 deletions.
2 changes: 1 addition & 1 deletion app/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@


class StateAdmin(admin.ModelAdmin):
list_display = ("device", "recipe", "environment", "peripherals", "controllers")
list_display = ("device", "recipe", "environment", "peripherals", "controllers", "iot", "resource")
admin.site.register(StateModel, StateAdmin)


Expand Down
9 changes: 9 additions & 0 deletions app/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,15 @@ def get_iot_dict():
return json.loads( state.iot )


def get_resource_dict():
""" Gets resource dict from state table in database. """
if not StateModel.objects.filter( pk=1 ).exists():
return None
else:
state = StateModel.objects.get( pk=1 )
return json.loads( state.resource )


def manage_event(event_request, timeout_seconds=3, update_interval_seconds=0.1):
""" Manages an event request. Creates new event in database, waits for
event response, returns event response or timeout error. """
Expand Down
22 changes: 22 additions & 0 deletions app/migrations/0006_statemodel_resource.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.4 on 2018-06-19 15:00
from __future__ import unicode_literals

import django.contrib.postgres.fields.jsonb
from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('app', '0005_statemodel_iot'),
]

operations = [
migrations.AddField(
model_name='statemodel',
name='resource',
field=django.contrib.postgres.fields.jsonb.JSONField(default=''),
preserve_default=False,
),
]
1 change: 1 addition & 0 deletions app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class StateModel(models.Model):
peripherals = JSONField()
controllers = JSONField()
iot = JSONField()
resource = JSONField()

class Meta:
verbose_name = "State"
Expand Down
2 changes: 1 addition & 1 deletion app/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class StateSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = StateModel
fields = ("device", "recipe", "environment", "peripherals",
"controllers", "iot")
"controllers", "iot", "resource")


class EventSerializer(serializers.HyperlinkedModelSerializer):
Expand Down
20 changes: 19 additions & 1 deletion app/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@

'app',
'device',
'iot'
'iot',
'resource'
]

MIDDLEWARE = [
Expand Down Expand Up @@ -159,6 +160,19 @@
'formatter': 'device_file',
'maxBytes': 5*1024*1024,
'backupCount': 1
},
'resource_console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'device_console',
},
'resource_file': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler',
'filename': os.path.dirname(BASE_DIR) + "/logs/resource.log",
'formatter': 'device_file',
'maxBytes': 5*1024*1024,
'backupCount': 1
}
},
'loggers': {
Expand All @@ -173,6 +187,10 @@
'iot': {
'handlers': ['iot_console', 'iot_file'],
'level': 'DEBUG',
},
'resource': {
'handlers': ['resource_console', 'resource_file'],
'level': 'DEBUG',
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions app/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@
<li {% if 'iot' in request.path %} class="active nav-item"{% else %} class="nav-item" {% endif %}>
<a class="nav-link" href="{% url 'iot' %}">IoT</a>
</li>
<li {% if 'resource' in request.path %} class="active nav-item"{% else %} class="nav-item" {% endif %}>
<a class="nav-link" href="{% url 'resource' %}">Resources</a>
</li>
<li {% if 'admin' in request.path %} class="active nav-item"{% else %} class="nav-item" {% endif %}>
<a class="nav-link" href="{% url 'admin:index' %}">Admin</a>
</li>
Expand Down
21 changes: 21 additions & 0 deletions app/templates/resource.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{% extends 'base.html' %}
{% block content %}
<html>
<body>
<div class="resource">
<div class="card">
<b>Resources</b>
<ul>
<li><b>Status:</b> {{ status }}
<li><b>Available disk space:</b> {{ available_disk_space }}
<li><b>Free memory:</b> {{ free_memory }}

{% if error != None %}
<li><b>Error:</b> {{ error }}
{% endif %}
</ul>
</div>
</div>
</body>
</html>
{% endblock %}
1 change: 1 addition & 0 deletions app/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ def redirect_to_dashboard(request):
url(r'^recipe/build/$', views.RecipeBuilder.as_view(), name="recipe-builder"),
url(r'^environments/$', views.Environments.as_view(), name="environments"),
url(r'^iot/$', views.IoT.as_view(), name="iot"),
url(r'^resource/$', views.Resource.as_view(), name="resource"),
url(r'^manual/$', views.Manual.as_view(), name="manual"),
url(r'^entry/$', views.Entry.as_view(), name="entry"),
url(r'^scratchpad/$', views.Scratchpad.as_view(), name="entry"),
Expand Down
5 changes: 5 additions & 0 deletions app/viewers.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,4 +270,9 @@ def __init__(self):
self.iot_dict = Common.get_iot_dict()


class ResourceViewer:
resource_dict = {}
def __init__(self):
self.resource_dict = Common.get_resource_dict()


20 changes: 20 additions & 0 deletions app/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
from app.viewers import CultivarsViewer
from app.viewers import CultivationMethodsViewer
from app.viewers import IoTViewer
from app.viewers import ResourceViewer


# TODO: Clean up views. See https://github.com/phildini/api-driven-django/blob/master/votes/views.py
Expand Down Expand Up @@ -404,6 +405,25 @@ def get(self, request):
return Response( response )


class Resource(APIView):
""" UI page for ResourceManager. """
renderer_classes = [TemplateHTMLRenderer]
template_name = 'resource.html'

def get(self, request):

rv = ResourceViewer()

# Build and return response
response = {
"status": rv.resource_dict["status"],
"error": rv.resource_dict["error"],
"available_disk_space": rv.resource_dict["available_disk_space"],
"free_memory": rv.resource_dict["free_memory"]
}
return Response( response )


class Manual(APIView):
""" UI page for manual controls. """
renderer_classes = [TemplateHTMLRenderer]
Expand Down
12 changes: 10 additions & 2 deletions device/managers/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
# Import IoT communications (to the backend) manager
from iot.iot_manager import IoTManager

# Import resource manager
from resource.resource_manager import ResourceManager

# Import database models
from app.models import StateModel
from app.models import EventModel
Expand Down Expand Up @@ -100,6 +103,9 @@ def __init__(self):
self.iot = IoTManager( self.state, self )
self.latest_publish_timestamp = 0

# Initialize the resourcd manager object.
self.resource = ResourceManager( self.state, self, self.iot )


@property
def mode(self):
Expand Down Expand Up @@ -431,7 +437,8 @@ def update_state(self):
environment = json.dumps(self.state.environment),
peripherals = json.dumps(self.state.peripherals),
controllers = json.dumps(self.state.controllers),
iot = json.dumps(self.state.iot)
iot = json.dumps(self.state.iot),
resource = json.dumps(self.state.resource)
)
else:
StateModel.objects.filter(pk=1).update(
Expand All @@ -440,7 +447,8 @@ def update_state(self):
environment = json.dumps(self.state.environment),
peripherals = json.dumps(self.state.peripherals),
controllers = json.dumps(self.state.controllers),
iot = json.dumps(self.state.iot)
iot = json.dumps(self.state.iot),
resource = json.dumps(self.state.resource)
)


Expand Down
1 change: 1 addition & 0 deletions device/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class State(object):
peripherals = {}
controllers = {}
iot = {}
resource = {}


def set_environment_reported_sensor_value(self, sensor, variable, value, simple=False):
Expand Down
24 changes: 17 additions & 7 deletions iot/iot_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@ class IoTManager:
def __init__( self, state, ref_device_manager ):
""" Class constructor """
self.state = state
self.error = None
self.ref_device_manager = ref_device_manager
# Initialize our state. These are filled in by the IoTPubSub class
self.state.iot = {
"error": None,
"error": self.error,
"connected": 'No',
"received_message_count": 0,
"published_message_count": 0
}
self.ref_device_manager = ref_device_manager
self.error = None

self._stop_event = threading.Event() # so we can stop this thread
try:
Expand Down Expand Up @@ -103,8 +103,6 @@ def error( self ):
""" Gets error value. """
return self._error


#--------------------------------------------------------------------------
@error.setter
def error( self, value ):
""" Safely updates recipe error in shared state. """
Expand All @@ -113,6 +111,18 @@ def error( self, value ):
self.state.iot["error"] = value


#--------------------------------------------------------------------------
@property
def connected( self ):
return self.iot.connected


#--------------------------------------------------------------------------
def publishMessage( name, msg_json ):
""" Send a command reply. """
self.iot.publishCommandReply( name, msg_json )


#--------------------------------------------------------------------------
def spawn( self ):
self.logger.info("Spawning IoT thread")
Expand Down Expand Up @@ -160,8 +170,8 @@ def thread_proc( self ):
self.iot.publishCommandReply( "boot", about_json )
self.logger.info( "Published boot message with versions." )
except:
self.error = "Unable to load about.json file."
self.logger.critical( self.error )
self._error = "Unable to load about.json file."
self.logger.critical( self._error )


if self.stopped():
Expand Down
27 changes: 27 additions & 0 deletions upgrade.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/bin/bash

# Get the latest code
git pull

# Install any new python modules
source venv/bin/activate
pip install -r requirements.txt

# Recreate a fresh (empty) database
echo 'Recreating database...'
if [[ "$OSTYPE" == "linux"* ]]; then
sudo -u postgres psql -c "DROP DATABASE openag_brain;"
sudo -u postgres psql -c "CREATE DATABASE openag_brain OWNER openag;"
else # we are on OSX
psql postgres -c "DROP DATABASE openag_brain;"
psql postgres -c "CREATE DATABASE openag_brain OWNER openag;"
fi

# Load our models
echo 'Creating the django/postgres database...'
python manage.py migrate

# Clean up any files we don't need
rm logs/*.log logs/peripherals/*.log images/*.png


0 comments on commit e922156

Please sign in to comment.