Commit 42c26d44 by John Donnal

added new modules and project structure

parent 674f1495
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
.message{
background: #c2daf3;
margin: 4px;
padding: 8px;
border-radius: 0.4rem;
border-color: #007bff;
border-style: solid;
border-width: 2px;
margin-left: 10px;
font-weight: bold;
}
This diff could not be displayed because it is too large.
$(function () {
setInterval(loadData, 2000);
$("#update-interval").val(loadData);
});
function loadData(){
$.get("data.json", function (data) {
$("#data").text(data['random_value']);
});
}
function change_bkgd(){
let color = parseInt(Math.random()*0xFFFFFF).toString(16);
$(".jumbotron").css("background", "#"+color);
}
\ No newline at end of file
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
{% extends "layout.jinja2" %}
{% block title %} Bootstrap Interface {% endblock %}
{% block css %}
<link rel="stylesheet" href="assets/css/index.css">
{% endblock %}
{% block js %}
<script src="assets/js/index.js"></script>
{% endblock %}
{% block content %}
<div class="jumbotron jumbotron-fluid">
<div class="container">
<h1 class="display-4">Bootstrap Interface</h1>
<p class="lead">
This module uses CSS and Javascript to create an interactive UI
</p>
<hr class="my-4">
<ul class="list-group">
<!-- example of jinja2 data -->
<li class="list-group-item">Static value injected with jinja2:
<span class="message">{{ message }}</span>
</li>
<!-- example of AJAX data -->
<li class="list-group-item">Dynamic data loaded with AJAX:
<!-- see assets/index.js for AJAX code -->
<span id="data" class="message">&mdash;</span>
</li>
</ul>
<p class="lead mt-4">
<button class="btn btn-primary btn-lg" onclick="change_bkgd()">
Change Background
</button>
</p>
</div>
</div>
{% endblock %}
\ No newline at end of file
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="assets/css/bootstrap.min.css">
<!-- load the page specif CSS -->
{% block css %}{% endblock %}
<title>{% block title %} Default Title {% endblock %}</title>
</head>
<body>
<div class="container-fluid">
<!-- page specific content here -->
{% block content %}
Default Content
{% endblock %}
</div>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="assets/js/jquery-3.3.1.min.js"></script>
<script src="assets/js/popper.min.js"></script>
<script src="assets/js/bootstrap.bundle.min.js" ></script>
<!-- load the page specific js -->
{% block js %}{% endblock %}
</body>
</html>
\ No newline at end of file
#!/usr/bin/env python3
import asyncio
from aiohttp import web
from joule.client.reader_module import ReaderModule
import aiohttp_jinja2
import jinja2
import os
from random import randint
from joule.client.reader_module import ReaderModule
CSS_DIR = os.path.join(os.path.dirname(__file__), 'assets', 'css')
JS_DIR = os.path.join(os.path.dirname(__file__), 'assets', 'js')
......@@ -31,14 +35,18 @@ class BootstrapInterface(ReaderModule):
@aiohttp_jinja2.template('index.jinja2')
async def index(self, request):
return {'name': "Data Visualizer",
'version': 1.0}
return {'message': "hello world"}
# json end point for AJAX requests
async def data(self, request):
# return summary statistics, etc.
return web.json_response(data=[1,2,8])
return web.json_response(data={'random_value': randint(0, 10)})
if __name__ == "__main__":
r = ComplexInterface()
def main():
r = BootstrapInterface()
r.start()
if __name__ == "__main__":
main()
......@@ -6,34 +6,40 @@ from joule import CompositeModule, LocalNumpyPipe
from high_bandwidth_reader import HighBandwidthReader
from example_filter import ExampleFilter
class ExampleComposite(CompositeModule):
""" Merge reader and filter into a single module:
[reader -> filter]->
"""
async def setup(self, parsed_args,
inputs, outputs):
#1.) create nested modules
my_reader = HighBandwidthReader()
my_filter = ExampleFilter()
#2.) create local pipes for interior streams
pipe = LocalNumpyPipe(name="raw", layout="float32_1")
#3.) convert modules into tasks
# output is an interior stream (write-end)
parsed_args = argparse.Namespace(rate=100)
task1 = my_reader.run(parsed_args, pipe)
# raw is an interior stream (read-end)
# filtered is an exterior stream
parsed_args = argparse.Namespace()
task2 = my_filter.run(parsed_args,
{"raw": pipe},
{"filtered": outputs["filtered"]})
#4.) tasks are executed in the main event loop
return [task1, task2]
if __name__ == "__main__":
class ExampleComposite(CompositeModule):
""" Merge reader and filter into a single module:
[reader -> filter]->
"""
async def setup(self, parsed_args,
inputs, outputs):
# 1.) create nested modules
my_reader = HighBandwidthReader()
my_filter = ExampleFilter()
# 2.) create local pipes for interior streams
pipe = LocalNumpyPipe(name="raw", layout="float32_1")
# 3.) convert modules into tasks
# output is an interior stream (write-end)
parsed_args = argparse.Namespace(rate=100)
task1 = my_reader.run(parsed_args, pipe)
# raw is an interior stream (read-end)
# filtered is an exterior stream
parsed_args = argparse.Namespace()
task2 = my_filter.run(parsed_args,
{"raw": pipe},
{"filtered": outputs["filtered"]})
# 4.) tasks are executed in the main event loop
return [task1, task2]
def main():
r = ExampleComposite()
r.start()
if __name__ == "__main__":
main()
#!/usr/bin/python3
#!/usr/bin/env python3
from joule import FilterModule, EmptyPipe
from scipy.signal import medfilt
......@@ -33,6 +33,10 @@ class ExampleFilter(FilterModule):
await asyncio.sleep(1)
if __name__ == "__main__":
def main():
r = ExampleFilter()
r.start()
if __name__ == "__main__":
main()
#!/usr/bin/env python3
import asyncio
from aiohttp import web
from joule.client.reader_module import ReaderModule
from joule import ReaderModule
class ExampleInterface(ReaderModule):
......@@ -17,6 +19,10 @@ class ExampleInterface(ReaderModule):
return web.Response(text="hello world!")
if __name__ == "__main__":
r = ExampleVisualizer()
def main():
r = ExampleInterface()
r.start()
if __name__ == "__main__":
main()
#!/usr/bin/python3
#!/usr/bin/env python3
from joule import ReaderModule
from joule.utilities import time_now
......@@ -8,13 +8,18 @@ import numpy as np
class ExampleReader(ReaderModule):
"Example reader: generates random values"
async def run(self, parsed_args, output):
while(1):
while True:
value = np.random.rand() # data from sensor
await output.write(np.array([[time_now(), value]]))
await asyncio.sleep(1)
if __name__ == "__main__":
def main():
r = ExampleReader()
r.start()
if __name__ == "__main__":
main()
#!/usr/bin/python3
#!/usr/bin/env python3
from joule import ReaderModule
from joule.utilities import time_now
......@@ -7,7 +7,7 @@ import numpy as np
class HighBandwidthReader(ReaderModule):
#Produce sawtooth waveform at specified sample rate"
""" Produce a 1Hz ramp sampled at [rate] Hz """
def custom_args(self, parser):
grp = parser.add_argument_group("module",
......@@ -15,21 +15,26 @@ class HighBandwidthReader(ReaderModule):
grp.add_argument("--rate", type=float,
required=True,
help="sample rate in Hz")
async def run(self, parsed_args, output):
start_ts = time_now()
#run 5 times per second
period=1
samples_per_period=np.round(parsed_args.rate*period)
while(1):
end_ts = start_ts+period*1e6
ts = np.linspace(start_ts,end_ts,
samples_per_period,endpoint=False)
vals=np.linspace(0,33,samples_per_period)
# run 5 times per second
period = 1
samples_per_period = np.round(parsed_args.rate * period)
while True:
end_ts = start_ts + period * 1e6
ts = np.linspace(start_ts, end_ts,
samples_per_period, endpoint=False)
vals = np.linspace(0, 33, samples_per_period)
start_ts = end_ts
chunk = np.hstack((ts[:,None], vals[:,None]))
chunk = np.hstack((ts[:, None], vals[:, None]))
await output.write(chunk)
await asyncio.sleep(period)
if __name__ == "__main__":
def main():
r = HighBandwidthReader()
r.start()
if __name__ == "__main__":
main()
#!/usr/bin/env python3
from joule import ReaderModule
from joule.utilities import time_now
import asyncio
import numpy as np
import logging
ERROR_PROBABILITY = 0.25
class IntermittentReader(ReaderModule):
""" Like HighBandwidth reader with random data interruptions """
def custom_args(self, parser):
grp = parser.add_argument_group("module",
"module specific arguments")
grp.add_argument("--rate", type=float,
required=True,
help="sample rate in Hz")
async def run(self, parsed_args, output):
start_ts = time_now()
period = 1
samples_per_period = np.round(parsed_args.rate * period)
while True:
try:
end_ts = start_ts + period * 1e6
ts = np.linspace(start_ts, end_ts,
samples_per_period, endpoint=False)
vals = np.linspace(0, 33, samples_per_period)
start_ts = end_ts
chunk = np.hstack((ts[:, None], vals[:, None]))
# simulate an error
if np.random.rand() < ERROR_PROBABILITY:
raise ValueError
await output.write(chunk)
except ValueError:
logging.error("simulated data interruption")
await output.close_interval()
await asyncio.sleep(period)
def main():
r = IntermittentReader()
r.start()
if __name__ == "__main__":
main()
#!/usr/bin/python3
#!/usr/bin/env python3
from joule import FilterModule, EmptyPipe
......@@ -24,6 +24,10 @@ class OffsetFilter(FilterModule):
except EmptyPipe:
break
if __name__ == "__main__":
def main():
r = OffsetFilter()
r.start()
if __name__ == "__main__":
main()
......@@ -26,4 +26,5 @@ tzlocal==1.5.1
urllib3==1.23
yarl==1.2.6
Jinja2==2.10
aiohttp-jinja2==1.0.0
\ No newline at end of file
aiohttp-jinja2==1.0.0
joule
\ No newline at end of file
#!/usr/bin/env python
#!/usr/bin/env python3
from setuptools import setup
import versioneer
......@@ -44,7 +44,8 @@ setup(
'tabulate',
'sqlalchemy',
'aiohttp-jinja2',
'jinja2'],
'jinja2',
'joule'],
namespace_packages=[],
packages=['jouleexamples'],
include_package_data=True,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment