Added capture state endpoint

This commit is contained in:
Joel Collins 2018-11-12 12:22:06 +00:00
parent 52d667feec
commit 4e67d24841
7 changed files with 151 additions and 34 deletions

View file

@ -30,6 +30,19 @@ var fovY = 3146;
window.onload = function() {
getStagePositions()
updateTextBoxes()
getCaptures()
}
function getCaptures() {
function updateCapturesCallback(response, status) {
console.log(status);
updateCaptures(response);
}
safeRequest("GET", baseURI+"/capture", null, updateCapturesCallback, false)
}
function updateCaptures(response) {
console.log(response)
}
function updateTextBoxes() {
@ -50,20 +63,20 @@ function updateStagePositions(response) {
function getStagePositions() {
function updatePositionCallback(response, status) {
console.log(status, response);
updateStagePositions(response);
console.log(status, response);
updateStagePositions(response);
}
safeRequest("GET", baseURI+"/position", null, updatePositionCallback)
safeRequest("GET", baseURI+"/position", null, updatePositionCallback, false)
}
function setStagePositions(x_abs, y_abs, z_abs) {
// Make a position request
function absMoveCallback(response, status) {
if (status == 400) {
alert("Stage cannot be moved further than the safe range.");
}
console.log(status, response);
updateStagePositions(response);
if (status == 400) {
alert("Stage cannot be moved further than the safe range.");
}
console.log(status, response);
updateStagePositions(response);
}
safeRequest("POST", baseURI+"/position", { "absolute": true, "x": x_abs, "y": y_abs, "z": z_abs}, absMoveCallback)
}
@ -71,11 +84,11 @@ function setStagePositions(x_abs, y_abs, z_abs) {
function moveStagePositions(x_rel, y_rel, z_rel) {
// Make a position request
function relMoveCallback(response, status) {
if (status == 400) {
alert("Stage cannot be moved further than the safe range.");
}
console.log(status, response);
updateStagePositions(response);
if (status == 400) {
alert("Stage cannot be moved further than the safe range.");
}
console.log(status, response);
updateStagePositions(response);
}
safeRequest("POST", baseURI+"/position", { "absolute": false, "x": x_rel, "y": y_rel, "z": z_rel}, relMoveCallback)
}
@ -169,20 +182,32 @@ addEventListener("keyup", function (e) {
}, false);
// Methods for making requests
function safeRequest(method, url, payload, callback) {
if (requestLock == false) {
function safeRequest(method, url, payload, callback, lock=true, force=false) {
if (force == true) {
allowRequest = true;
}
else {
allowRequest = !(requestLock);
}
if (allowRequest == true) {
var xhr = new XMLHttpRequest(); // new HttpRequest instance
xhr.open(method, url);
requestLock = true;
if (lock == true) {
requestLock = true;
}
xhr.onload = function (e) {
if (xhr.readyState === 4) {
if (xhr.status !== 200) {
console.error(xhr.statusText);
}
callback(JSON.parse(xhr.responseText), xhr.status);
}
requestLock = false;
if (xhr.readyState === 4) {
if (xhr.status !== 200) {
console.error(xhr.statusText);
}
callback(JSON.parse(xhr.responseText), xhr.status);
}
if (lock == true) {
requestLock = false;
}
};
if (method == "POST" || method == "PUT") {

View file

@ -64,3 +64,12 @@ img {
display: table;
}
/* Data divs */
#captures {
font-size:12px;
}
.capture {
background-color: #d3d3d3;
}

View file

@ -73,7 +73,11 @@
<div class="column right">
<h2>Captures</h2>
<p>Not yet implemented.</p>
<div id="captures">
<p>Not yet implemented.</p>
<div class="capture">Capture 1</div>
</div>
</div>
<div class="column middle">

View file

@ -13,3 +13,14 @@ def gen(camera):
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
def get_bool(get_arg):
"""Convert GET request argument string to a Python bool"""
if (
get_arg == 'true' or
get_arg == 'True' or
get_arg == '1'):
return True
else:
return False

View file

@ -1,5 +1,6 @@
#!/usr/bin/env python
"""
TODO: Add proper docstrings
TODO: Bind to port 80
TODO: Reimplement capture methods
TODO: Implement API route to cleanly shut down server
@ -18,7 +19,7 @@ from flask import (
import numpy as np
from openflexure_microscope.api.utilities import parse_payload, gen
from openflexure_microscope.api.utilities import parse_payload, gen, get_bool
from openflexure_microscope import Microscope
from openflexure_microscope.camera.pi import StreamingCamera
@ -59,6 +60,9 @@ def stream():
"""Video streaming route. Put this in the src attribute of an img tag."""
global microscope
# Restart stream worker thread
microscope.camera.start_worker()
return Response(
gen(microscope.camera),
mimetype='multipart/x-mixed-replace; boundary=frame')
@ -115,5 +119,59 @@ def position():
return jsonify(microscope.state['position'])
# Capture routes
@app.route(uri('/capture'), methods=['GET', 'POST', 'PUT'])
def capture():
"""Return JSONified microscope state"""
global microscope
if request.method == 'POST' or request.method == 'PUT':
state = parse_payload(request)
print(state)
if 'filename' in state:
filename = state['filename']
else:
filename = None
if 'keep_on_disk' in state:
keep_on_disk = bool(state['keep_on_disk'])
else:
keep_on_disk = True
if 'use_video_port' in state:
use_video_port = bool(state['use_video_port'])
else:
use_video_port = False
if 'size' in state:
if 'width' in state['size'] and 'height' in state['size']:
resize = (state['size']['width'], state['size']['height'])
else:
raise Exception("Invalid resize parameters passed. Ensure both width and height are specified.")
else:
resize = None
capture_obj = microscope.camera.capture(
write_to_file=True, # Always write data to disk when using API
keep_on_disk=keep_on_disk,
use_video_port=use_video_port,
filename=filename,
resize=resize)
return jsonify(capture_obj.metadata)
else: # GET requests
include_unavailable = get_bool(request.args.get('include_unavailable'))
if include_unavailable:
captures = [image for image in microscope.camera.images if image.metadata['available']]
else:
captures = microscope.camera.images
metadata_array = [capture.metadata for capture in captures]
return jsonify(metadata_array)
if __name__ == '__main__':
app.run(host='0.0.0.0', threaded=True, debug=True, use_reloader=False)