Skip to content

Commit

Permalink
Merge pull request #421 from DeepwaterExploration/system_api
Browse files Browse the repository at this point in the history
System api
  • Loading branch information
brandonhs authored Oct 3, 2024
2 parents 4709ba6 + 97400bc commit d74b427
Show file tree
Hide file tree
Showing 114 changed files with 1,679 additions and 3,182 deletions.
4 changes: 0 additions & 4 deletions backend_py/build.sh

This file was deleted.

13 changes: 9 additions & 4 deletions backend_py/clean.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
#!/bin/bash
rm -rf build || true
rm -rf src/__pycache__ || true
rm -rf src/devices/__pycache__ || true
rm -rf src/lights/__pycache__ || true

# Remove the build directory if it exists
find . -type f -name "*.so" -exec rm {} +

# Find and remove all __pycache__ directories
find . -type d -name "__pycache__" -exec rm -rf {} +

# Remove the device_settings.json file if it exists
rm -f device_settings.json || true
rm -f server_preferences.json || true
3 changes: 2 additions & 1 deletion backend_py/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ marshmallow==3.22.0
natsort==8.4.0
PyEventEmitter==1.0.5
rpi_hardware_pwm==0.2.2
websockets==12.0
websockets==12.0
dbus-python==1.2.18
5 changes: 3 additions & 2 deletions backend_py/run.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from src import main, logging
from src import Server, logging

logging.getLogger().setLevel(logging.INFO)

main()
server = Server()
server.serve()
193 changes: 1 addition & 192 deletions backend_py/src/__init__.py
Original file line number Diff line number Diff line change
@@ -1,192 +1 @@
from ctypes import *
import sys
import signal

from flask import Flask, jsonify, request
from flask_cors import CORS
from gevent.pywsgi import WSGIServer

from .enumeration import *
from .camera_helper_loader import *
from .schemas import *
from .device import *
from .stream import *
from .settings import SettingsManager
from .broadcast_server import BroadcastServer
from .device_manager import DeviceManager
from .lights.light_manager import LightManager
from .lights.utils import create_pwm_controllers
from .preferences.preferences_manager import PreferencesManager
from .preferences.preference_schemas import SavedPrefrencesSchema, SavedPrefrences

import logging


def main():
# Create the flask application
app = Flask(__name__)
CORS(app)
# avoid sorting the keys to keep the way we sort it in the backend
app.json.sort_keys = False

# Create the managers
settings_manager = SettingsManager()
broadcast_server = BroadcastServer()
device_manager = DeviceManager(
settings_manager=settings_manager, broadcast_server=broadcast_server)
light_manager = LightManager(create_pwm_controllers())
preferences_manager = PreferencesManager()

'''
Logs API
'''
@app.route('/logs', methods=['GET'])
def get_logs():
return jsonify(device_manager.get_logs())

'''
Device API
'''
@app.route('/devices', methods=['GET'])
def get_devices():
return jsonify(device_manager.get_devices())

@app.route('/devices/set_option', methods=['POST'])
def set_option():
option_value = OptionValueSchema().load(request.get_json())

device_manager.set_device_option(
option_value['bus_info'], option_value['option'], option_value['value'])

return jsonify({})

@app.route('/devices/configure_stream', methods=['POST'])
def configure_stream():
stream_info = StreamInfoSchema().load(request.get_json())

device_manager.configure_device_stream(
stream_info['bus_info'], stream_info)

return jsonify({})

@app.route('/devices/unconfigure_stream', methods=['POST'])
def unconfigure_stream():
bus_info = StreamInfoSchema(only=['bus_info']).load(
request.get_json())['bus_info']

device_manager.uncofigure_device_stream(bus_info)

return jsonify({})

@app.route('/devices/set_nickname', methods=['POST'])
def set_nickname():
device_nickname = DeviceNicknameSchema().load(request.get_json())

device_manager.set_device_nickname(
device_nickname['bus_info'], device_nickname['nickname'])

return jsonify({})

@app.route('/devices/set_uvc_control', methods=['POST'])
def set_uvc_control():
uvc_control = UVCControlSchema().load(request.get_json())

device_manager.set_device_uvc_control(
uvc_control['bus_info'], uvc_control['control_id'], uvc_control['value'])

return jsonify({})

@app.route('/devices/leader_bus_infos')
def get_leader_bus_infos():
bus_infos = []
for device in device_manager.devices:
if device.device_type == DeviceType.STELLARHD_LEADER:
bus_infos.append({
'nickname': device.nickname,
'bus_info': device.bus_info
})

return jsonify(bus_infos)

@app.route('/devices/set_leader', methods=['POST'])
def set_leader():
leader_schema = DeviceLeaderSchema().load(request.get_json())
device_manager.set_leader(leader_schema['leader'], leader_schema['follower'])
return jsonify({})

@app.route('/devices/remove_leader', methods=['POST'])
def remove_leader():
leader_schema = DeviceLeaderSchema().load(request.get_json())
device_manager.remove_leader(leader_schema['follower'])
return jsonify({})

@app.route('/devices/restart_stream', methods=['POST'])
def restart_stream():
bus_info = StreamInfoSchema(only=['bus_info']).load(request.get_json())['bus_info']
dev = device_manager._find_device_with_bus_info(bus_info)
if not dev:
logging.warning(f'Unable to find device {bus_info}')
return jsonify({})
dev.start_stream()
return jsonify({})

'''
Lights API
'''
@app.route('/lights')
def get_lights():
return jsonify(light_manager.get_lights())

@app.route('/lights/controllers')
def get_pwm_controllers():
return jsonify(light_manager.get_pwm_controllers())

@app.route('/lights/set_intensity', methods=['POST'])
def set_intensity():
req = request.get_json()
light_manager.set_intensity(req['index'], req['intensity'])
return jsonify({})

@app.route('/lights/disable_pin', methods=['POST'])
def disable_light():
req = request.get_json()
light_manager.disable_light(req['controller_index'], req['pin'])
return jsonify({})

'''
Preferences API
'''
@app.route('/preferences')
def get_preferences():
return jsonify(preferences_manager.serialize_preferences())

@app.route('/preferences/save_preferences', methods=['POST'])
def set_preferences():
req: SavedPrefrences = SavedPrefrencesSchema().load(request.get_json())
preferences_manager.save(req)
return jsonify({})

# create the server and run everything
http_server = WSGIServer(('0.0.0.0', 8080), app, log=None)
device_manager.start_monitoring()

def exit_clean(sig, frame):
logging.info('Shutting down')

light_manager.cleanup()

http_server.stop()
device_manager.stop_monitoring()
broadcast_server.kill()

sys.exit(0)

broadcast_server.run_in_background()
signal.signal(signal.SIGINT, exit_clean)

logging.info('Starting backend server on http://0.0.0.0:8080')
http_server.serve_forever()


if __name__ == '__main__':
main()
from .server import *
5 changes: 5 additions & 0 deletions backend_py/src/blueprints/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from .cameras import *
from .lights import *
from .logs import *
from .preferences import *
from .wifi import *
109 changes: 109 additions & 0 deletions backend_py/src/blueprints/cameras.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
from flask import Blueprint, request, jsonify, current_app
from ..services import DeviceManager, OptionValueSchema, StreamInfoSchema, DeviceNicknameSchema, UVCControlSchema, DeviceType, DeviceLeaderSchema
import logging

cameras_bp = Blueprint('cameras', __name__)

@cameras_bp.route('/devices', methods=['GET'])
def get_devices():
device_manager: DeviceManager = current_app.config['device_manager']

return jsonify(device_manager.get_devices())

@cameras_bp.route('/devices/set_option', methods=['POST'])
def set_option():
device_manager: DeviceManager = current_app.config['device_manager']

option_value = OptionValueSchema().load(request.get_json())

device_manager.set_device_option(
option_value['bus_info'], option_value['option'], option_value['value'])

return jsonify({})

@cameras_bp.route('/devices/configure_stream', methods=['POST'])
def configure_stream():
device_manager: DeviceManager = current_app.config['device_manager']

stream_info = StreamInfoSchema().load(request.get_json())

device_manager.configure_device_stream(
stream_info['bus_info'], stream_info)

return jsonify({})

@cameras_bp.route('/devices/unconfigure_stream', methods=['POST'])
def unconfigure_stream():
device_manager: DeviceManager = current_app.config['device_manager']

bus_info = StreamInfoSchema(only=['bus_info']).load(
request.get_json())['bus_info']

device_manager.uncofigure_device_stream(bus_info)

return jsonify({})

@cameras_bp.route('/devices/set_nickname', methods=['POST'])
def set_nickname():
device_manager: DeviceManager = current_app.config['device_manager']

device_nickname = DeviceNicknameSchema().load(request.get_json())

device_manager.set_device_nickname(
device_nickname['bus_info'], device_nickname['nickname'])

return jsonify({})

@cameras_bp.route('/devices/set_uvc_control', methods=['POST'])
def set_uvc_control():
device_manager: DeviceManager = current_app.config['device_manager']

uvc_control = UVCControlSchema().load(request.get_json())

device_manager.set_device_uvc_control(
uvc_control['bus_info'], uvc_control['control_id'], uvc_control['value'])

return jsonify({})

@cameras_bp.route('/devices/leader_bus_infos')
def get_leader_bus_infos():
device_manager: DeviceManager = current_app.config['device_manager']

bus_infos = []
for device in device_manager.devices:
if device.device_type == DeviceType.STELLARHD_LEADER:
bus_infos.cameras_bpend({
'nickname': device.nickname,
'bus_info': device.bus_info
})

return jsonify(bus_infos)

@cameras_bp.route('/devices/set_leader', methods=['POST'])
def set_leader():
device_manager: DeviceManager = current_app.config['device_manager']

leader_schema = DeviceLeaderSchema().load(request.get_json())
device_manager.set_leader(leader_schema['leader'], leader_schema['follower'])
return jsonify({})

@cameras_bp.route('/devices/remove_leader', methods=['POST'])
def remove_leader():
device_manager: DeviceManager = current_app.config['device_manager']

leader_schema = DeviceLeaderSchema().load(request.get_json())
device_manager.remove_leader(leader_schema['follower'])
return jsonify({})

@cameras_bp.route('/devices/restart_stream', methods=['POST'])
def restart_stream():
device_manager: DeviceManager = current_app.config['device_manager']

bus_info = StreamInfoSchema(only=['bus_info']).load(request.get_json())['bus_info']
dev = device_manager._find_device_with_bus_info(bus_info)
if not dev:
logging.warning(f'Unable to find device {bus_info}')
return jsonify({})

dev.start_stream()
return jsonify({})
32 changes: 32 additions & 0 deletions backend_py/src/blueprints/lights.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from flask import Blueprint, request, jsonify, current_app
from ..services import LightManager

lights_bp = Blueprint('lights', __name__)

@lights_bp.route('/lights')
def get_lights():
light_manager: LightManager = current_app.config['light_manager']

return jsonify(light_manager.get_lights())

@lights_bp.route('/lights/controllers')
def get_pwm_controllers():
light_manager: LightManager = current_app.config['light_manager']

return jsonify(light_manager.get_pwm_controllers())

@lights_bp.route('/lights/set_intensity', methods=['POST'])
def set_intensity():
light_manager: LightManager = current_app.config['light_manager']

req = request.get_json()
light_manager.set_intensity(req['index'], req['intensity'])
return jsonify({})

@lights_bp.route('/lights/disable_pin', methods=['POST'])
def disable_light():
light_manager: LightManager = current_app.config['light_manager']

req = request.get_json()
light_manager.disable_light(req['controller_index'], req['pin'])
return jsonify({})
10 changes: 10 additions & 0 deletions backend_py/src/blueprints/logs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from flask import Blueprint, jsonify, current_app
from ..logging import LogHandler

logs_bp = Blueprint('logs', __name__)

@logs_bp.route('/logs', methods=['GET'])
def get_logs():
log_handler: LogHandler = current_app.config['log_handler']

return jsonify(log_handler.logs)
Loading

0 comments on commit d74b427

Please sign in to comment.