Display all params
This commit is contained in:
parent
7eb06bbd57
commit
7ea52bc571
|
|
@ -1,4 +1,4 @@
|
||||||
from flask import Blueprint, render_template, request, redirect
|
from flask import Blueprint, render_template, request, send_file, jsonify
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from .. import camera as C
|
from .. import camera as C
|
||||||
|
|
@ -11,61 +11,93 @@ blueprint = Blueprint('camera', __name__)
|
||||||
@blueprint.route('/')
|
@blueprint.route('/')
|
||||||
def get():
|
def get():
|
||||||
"""
|
"""
|
||||||
Returns the page showing camera configuration
|
Returns the page showing camera configuration for all parameters in capturesettings and imgsettings,
|
||||||
|
grouped by section.
|
||||||
"""
|
"""
|
||||||
# Load configCamera.json
|
# Load configCamera.json
|
||||||
with open('configCamera.json', 'r') as f:
|
with open('configCamera.json', 'r') as f:
|
||||||
config = json.load(f)
|
config = json.load(f)
|
||||||
|
|
||||||
# Extract shutterspeed choices and current value
|
grouped_params = []
|
||||||
shutterspeed = config['main']['capturesettings']['shutterspeed']
|
for section in ['capturesettings', 'imgsettings']:
|
||||||
shutterspeed_choices = [
|
section_params = []
|
||||||
|
settings = config['main'].get(section, {})
|
||||||
|
for param_name, param in settings.items():
|
||||||
|
if 'Choices' in param and isinstance(param['Choices'], list) and param['Choices']:
|
||||||
|
choices = [
|
||||||
{'value': c.get('id', idx), 'label': c['label']}
|
{'value': c.get('id', idx), 'label': c['label']}
|
||||||
for idx, c in enumerate(shutterspeed['Choices'])
|
for idx, c in enumerate(param['Choices'])
|
||||||
]
|
]
|
||||||
shutterspeed_current = shutterspeed['Current']
|
if len(choices) > 1:
|
||||||
|
section_params.append({
|
||||||
|
'name': param_name,
|
||||||
|
'label': param.get('Label', param_name.capitalize()),
|
||||||
|
'choices': choices,
|
||||||
|
'current': param.get('Current', '')
|
||||||
|
})
|
||||||
|
if section_params:
|
||||||
|
grouped_params.append({
|
||||||
|
'section': section,
|
||||||
|
'params': section_params
|
||||||
|
})
|
||||||
|
|
||||||
# Extract aperture choices and current value
|
import pprint
|
||||||
aperture = config['main']['capturesettings']['aperture']
|
pprint.pprint(grouped_params)
|
||||||
aperture_choices = [
|
|
||||||
{'value': c.get('id', idx), 'label': c['label']}
|
|
||||||
for idx, c in enumerate(aperture['Choices'])
|
|
||||||
]
|
|
||||||
aperture_current = aperture['Current']
|
|
||||||
|
|
||||||
return render_template(
|
return render_template(
|
||||||
'camera.html',
|
'camera.html',
|
||||||
shutterspeed_choices=shutterspeed_choices,
|
grouped_params=grouped_params
|
||||||
shutterspeed_current=shutterspeed_current,
|
|
||||||
aperture_choices=aperture_choices,
|
|
||||||
aperture_current=aperture_current
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@blueprint.route('/set', methods=['POST'])
|
@blueprint.route('/set', methods=['POST'])
|
||||||
def set_camera_settings():
|
def set_camera_settings():
|
||||||
"""
|
"""
|
||||||
Receives and processes new camera settings (shutterspeed, aperture) from the client.
|
Receives and processes new camera settings for all parameters from the client.
|
||||||
"""
|
"""
|
||||||
data = request.get_json()
|
data = request.get_json()
|
||||||
shutterspeed = data.get('shutterspeed')
|
updated = {}
|
||||||
aperture = data.get('aperture')
|
for key, value in data.items():
|
||||||
|
print(f"Received {key}: {value}")
|
||||||
if shutterspeed is not None:
|
C.set_config(key, value)
|
||||||
print(f"Received shutterspeed: {shutterspeed}")
|
updated[key] = value
|
||||||
C.set_config('shutterspeed', shutterspeed)
|
return {'status': 'ok', **updated}
|
||||||
|
|
||||||
if aperture is not None:
|
|
||||||
print(f"Received aperture: {aperture}")
|
|
||||||
C.set_config('aperture', aperture)
|
|
||||||
|
|
||||||
return {'status': 'ok', 'shutterspeed': shutterspeed, 'aperture': aperture}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# filepath: /home/nicolas/dev/git/git.polymny.net/source/nenuscanner/src/nenuscanner/routes/camera.py
|
|
||||||
from flask import send_file
|
|
||||||
|
|
||||||
@blueprint.route('/feed.jpg')
|
@blueprint.route('/feed.jpg')
|
||||||
def camera_feed():
|
def camera_feed():
|
||||||
return send_file('static/feed.jpg', mimetype='image/jpeg')
|
return send_file('static/feed.jpg', mimetype='image/jpeg')
|
||||||
|
|
||||||
|
|
||||||
|
@blueprint.route('/config', methods=['GET'])
|
||||||
|
def get_camera_config():
|
||||||
|
"""
|
||||||
|
Returns grouped camera parameters as JSON for frontend JS.
|
||||||
|
"""
|
||||||
|
with open('configCamera.json', 'r') as f:
|
||||||
|
config = json.load(f)
|
||||||
|
|
||||||
|
grouped_params = []
|
||||||
|
for section in ['capturesettings', 'imgsettings']:
|
||||||
|
section_params = []
|
||||||
|
settings = config['main'].get(section, {})
|
||||||
|
for param_name, param in settings.items():
|
||||||
|
if 'Choices' in param and isinstance(param['Choices'], list) and param['Choices']:
|
||||||
|
choices = [
|
||||||
|
{'value': c.get('id', idx), 'label': c['label']}
|
||||||
|
for idx, c in enumerate(param['Choices'])
|
||||||
|
]
|
||||||
|
if len(choices) > 1:
|
||||||
|
section_params.append({
|
||||||
|
'name': param_name,
|
||||||
|
'label': param.get('Label', param_name.capitalize()),
|
||||||
|
'choices': choices,
|
||||||
|
'current': param.get('Current', '')
|
||||||
|
})
|
||||||
|
if section_params:
|
||||||
|
grouped_params.append({
|
||||||
|
'section': section,
|
||||||
|
'params': section_params
|
||||||
|
})
|
||||||
|
|
||||||
|
return jsonify(grouped_params)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,53 +4,36 @@
|
||||||
<section class="section">
|
<section class="section">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h1 class="title">Configurer la camera</h1>
|
<h1 class="title">Configurer la camera</h1>
|
||||||
|
<form id="camera-config-form">
|
||||||
<div class="field is-grouped is-grouped-multiline">
|
|
||||||
<div class="control">
|
|
||||||
<button> Lire la configuration actuelle</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<form action="/camera/set" method="POST">
|
|
||||||
<div class="columns">
|
<div class="columns">
|
||||||
<!-- Left column: Camera controls -->
|
|
||||||
<div class="column is-half">
|
<div class="column is-half">
|
||||||
|
{% for group in grouped_params %}
|
||||||
|
<div class="box">
|
||||||
|
<h2 class="subtitle has-text-weight-bold">
|
||||||
|
{{ group.section | replace('settings', ' Settings') | capitalize }}
|
||||||
|
</h2>
|
||||||
|
{% for param in group.params %}
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label class="label" for="shutterspeed">Shutter Speed:</label>
|
<label class="label" for="{{ param.name }}">{{ param.label }}:</label>
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<div class="select is-fullwidth">
|
<div class="select is-fullwidth">
|
||||||
<select id="shutterspeed" name="shutterspeed">
|
<select id="{{ param.name }}" name="{{ param.name }}">
|
||||||
{% for choice in shutterspeed_choices %}
|
{% for choice in param.choices %}
|
||||||
<option value="{{ choice.value }}" {% if choice.label == shutterspeed_current %}selected{% endif %}>
|
<option value="{{ choice.value }}" {% if choice.label == param.current %}selected{% endif %}>
|
||||||
{{ choice.value }} {{ choice.label }}
|
{{ choice.label }} ({{ choice.value }})
|
||||||
</option>
|
</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="control mt-2">
|
<div class="control mt-2">
|
||||||
<button class="button is-small is-primary" name="validate-shutterspeed">Set</button>
|
<button class="button is-small is-primary" type="button" onclick="setConfig('{{ param.name }}')">Set</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
|
||||||
<label class="label" for="aperture">Aperture:</label>
|
|
||||||
<div class="control">
|
|
||||||
<div class="select is-fullwidth">
|
|
||||||
<select id="aperture" name="aperture">
|
|
||||||
{% for choice in aperture_choices %}
|
|
||||||
<option value="{{ choice.value }}" {% if choice.label == aperture_current %}selected{% endif %}>
|
|
||||||
{{ choice.value }} {{ choice.label }}
|
|
||||||
</option>
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
|
||||||
</div>
|
</div>
|
||||||
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
<div class="control mt-2">
|
|
||||||
<button class="button is-small is-primary" name="validate-aperture" type="button">Set</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- Right column: Camera preview -->
|
|
||||||
<div class="column is-half has-text-centered">
|
<div class="column is-half has-text-centered">
|
||||||
<figure class="image is-4by3" style="max-width: 480px; margin: auto;">
|
<figure class="image is-4by3" style="max-width: 480px; margin: auto;">
|
||||||
<img id="camera-preview" src="/camera/feed.jpg?{{ range(1000000)|random }}" alt="Camera Preview" style="border: 1px solid #ccc;">
|
<img id="camera-preview" src="/camera/feed.jpg?{{ range(1000000)|random }}" alt="Camera Preview" style="border: 1px solid #ccc;">
|
||||||
|
|
@ -65,42 +48,27 @@
|
||||||
|
|
||||||
{% block extrajs %}
|
{% block extrajs %}
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
function setConfig(paramName) {
|
||||||
document.querySelector('button[name="validate-shutterspeed"]').addEventListener('click', async function(e) {
|
const value = document.getElementById(paramName).value;
|
||||||
e.preventDefault();
|
fetch('/camera/set', {
|
||||||
const value = document.getElementById('shutterspeed').value;
|
|
||||||
await fetch('/camera/set', {
|
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: { 'Content-Type': 'application/json' },
|
||||||
'Content-Type': 'application/json'
|
body: JSON.stringify({ [paramName]: value })
|
||||||
},
|
}).then(() => location.reload());
|
||||||
body: JSON.stringify({ shutterspeed: value })
|
}
|
||||||
});
|
|
||||||
location.reload();
|
|
||||||
});
|
|
||||||
|
|
||||||
document.querySelector('button[name="validate-aperture"]').addEventListener('click', async function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
const value = document.getElementById('aperture').value;
|
|
||||||
await fetch('/camera/set', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
},
|
|
||||||
body: JSON.stringify({ aperture: value })
|
|
||||||
});
|
|
||||||
location.reload();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Refresh preview image without reloading the page
|
|
||||||
window.refreshPreview = function() {
|
window.refreshPreview = function() {
|
||||||
const img = document.getElementById('camera-preview');
|
const img = document.getElementById('camera-preview');
|
||||||
const url = '/camera/feed.jpg?' + new Date().getTime();
|
const url = '/camera/feed.jpg?' + new Date().getTime();
|
||||||
img.src = url;
|
img.src = url;
|
||||||
}
|
}
|
||||||
|
//setInterval(window.refreshPreview, 2000);
|
||||||
|
|
||||||
// Automatically refresh every 2 seconds
|
fetch('/camera/config')
|
||||||
setInterval(window.refreshPreview, 2000);
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
// data is grouped_params, you can now dynamically build selects in JS
|
||||||
|
console.log(data);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock extrajs %}
|
{% endblock extrajs %}
|
||||||
Loading…
Reference in New Issue