GeezerVison is showing github.com — cherry pick: fix coderbot init, program load (#203) (#204) · CoderBotOrg/backend@0b80475
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: coderbot/api.py +1-10Lines changed: 1 addition & 10 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 27 | 27 |
| 28 | 28 | BUTTON_PIN = 16 | 29 | 29 |
| 30 | | -config = Config.read() | 31 | | -bot = CoderBot.get_instance(motor_trim_factor=float(config.get('move_motor_trim', 1.0)), | 32 | | - motor_max_power=int(config.get('motor_max_power', 100)), | 33 | | - motor_min_power=int(config.get('motor_min_power', 0)), | 34 | | - hw_version=config.get('hardware_version'), | 35 | | - pid_params=(float(config.get('pid_kp', 1.0)), | 36 | | - float(config.get('pid_kd', 0.1)), | 37 | | - float(config.get('pid_ki', 0.01)), | 38 | | - float(config.get('pid_max_speed', 200)), | 39 | | - float(config.get('pid_sample_time', 0.01)))) | | 30 | +bot = CoderBot.get_instance() | 40 | 31 | audio_device = Audio.get_instance() | 41 | 32 | cam = Camera.get_instance() | 42 | 33 |
| |
Collapse file Copy file name to clipboardExpand all lines: coderbot/audio.py +1-1Lines changed: 1 addition & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
| 26 | 26 | import pyaudio | 27 | 27 | import alsaaudio | 28 | 28 |
| 29 | | -from six.moves import queue | | 29 | +import queue | 30 | 30 | # [END import_libraries] | 31 | 31 |
| 32 | 32 | # Audio recording parameters | |
Collapse file Copy file name to clipboardExpand all lines: coderbot/coderbot.py +4-3Lines changed: 4 additions & 3 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -157,8 +157,10 @@ def exit(self): | 157 | 157 | s.cancel() | 158 | 158 |
| 159 | 159 | @classmethod | 160 | | - def get_instance(cls, motor_trim_factor=1.0, motor_max_power=100, motor_min_power=0, hw_version="5", pid_params=(0.8, 0.1, 0.01, 200, 0.01)): | | 160 | + def get_instance(cls, motor_trim_factor=1.0, motor_max_power=100, motor_min_power=0, hw_version="5", pid_params=(0.8, 0.1, 0.01, 200, 0.01), from_defaults=True): | 161 | 161 | if not cls.the_bot: | | 162 | + if from_defaults: | | 163 | + raise ValueError("incorrect CoderBot initialisation") | 162 | 164 | cls.the_bot = CoderBot(motor_trim_factor=motor_trim_factor, motor_max_power= motor_max_power, motor_min_power=motor_min_power, hw_version=hw_version, pid_params=pid_params) | 163 | 165 | return cls.the_bot | 164 | 166 |
| @@ -272,5 +274,4 @@ def _cb_button(self, gpio, level, tick): | 272 | 274 | elif tick - self._cb_last_tick[gpio] > elapse: | 273 | 275 | self._cb_last_tick[gpio] = tick | 274 | 276 | logging.info("pushed: %d, %d", level, tick) | 275 | | - cb() | 276 | | - | | 277 | + cb() |
Collapse file Copy file name to clipboardExpand all lines: coderbot/main.py +27-18Lines changed: 27 additions & 18 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 8 | 8 | import picamera | 9 | 9 | import connexion | 10 | 10 |
| 11 | | -from flask_cors import CORS | | 11 | +from connexion.options import SwaggerUIOptions | | 12 | +from connexion.middleware import MiddlewarePosition | | 13 | +from starlette.middleware.cors import CORSMiddleware | 12 | 14 |
| 13 | 15 | from camera import Camera | 14 | 16 | from motion import Motion | | 22 | 24 | # Logging configuration | 23 | 25 | logger = logging.getLogger() | 24 | 26 | logger.setLevel(os.environ.get("LOGLEVEL", "INFO")) | 25 | | -# sh = logging.StreamHandler() | 26 | | -# formatter = logging.Formatter('%(message)s') | 27 | | -# sh.setFormatter(formatter) | 28 | | -# logger.addHandler(sh) | 29 | 27 |
| 30 | 28 | ## (Connexion) Flask app configuration | 31 | 29 |
| 32 | 30 | # Serve a custom version of the swagger ui (Jinja2 templates) based on the default one | 33 | 31 | # from the folder 'swagger-ui'. Clone the 'swagger-ui' repository inside the backend folder | 34 | | -options = {"swagger_ui": False} | 35 | | -connexionApp = connexion.App(__name__, options=options) | 36 | | - | 37 | | -# Connexion wraps FlaskApp, so app becomes connexionApp.app | 38 | | -app = connexionApp.app | 39 | | -# Access-Control-Allow-Origin | 40 | | -CORS(app) | 41 | | -app.debug = False | | 32 | +swagger_ui_options = SwaggerUIOptions(swagger_ui=True) | | 33 | +app = connexion.App(__name__, swagger_ui_options=swagger_ui_options) | | 34 | +app.add_middleware( | | 35 | + CORSMiddleware, | | 36 | + position=MiddlewarePosition.BEFORE_EXCEPTION, | | 37 | + allow_origins=["*"], | | 38 | + allow_credentials=True, | | 39 | + allow_methods=["*"], | | 40 | + allow_headers=["*"], | | 41 | +) | 42 | 42 | app.prog_engine = ProgramEngine.get_instance() | 43 | 43 |
| 44 | 44 | ## New API and web application | 45 | 45 |
| 46 | 46 | # API v1 is defined in v1.yml and its methods are in api.py | 47 | | -connexionApp.add_api('v1.yml') | | 47 | +app.add_api('v1.yml') | 48 | 48 |
| 49 | 49 | def button_pushed(): | 50 | 50 | if app.bot_config.get('button_func') == "startstop": | @@ -67,8 +67,16 @@ def run_server(): | 67 | 67 | try: | 68 | 68 | try: | 69 | 69 | app.bot_config = Config.read() | 70 | | - | 71 | | - bot = CoderBot.get_instance() | | 70 | + bot = CoderBot.get_instance(motor_trim_factor=float(app.bot_config.get('move_motor_trim', 1.0)), | | 71 | + motor_max_power=int(app.bot_config.get('motor_max_power', 100)), | | 72 | + motor_min_power=int(app.bot_config.get('motor_min_power', 0)), | | 73 | + hw_version=app.bot_config.get('hardware_version'), | | 74 | + pid_params=(float(app.bot_config.get('pid_kp', 1.0)), | | 75 | + float(app.bot_config.get('pid_kd', 0.1)), | | 76 | + float(app.bot_config.get('pid_ki', 0.01)), | | 77 | + float(app.bot_config.get('pid_max_speed', 200)), | | 78 | + float(app.bot_config.get('pid_sample_time', 0.01))), | | 79 | + from_defaults=False) | 72 | 80 |
| 73 | 81 | try: | 74 | 82 | audio_device = Audio.get_instance() | @@ -78,6 +86,7 @@ def run_server(): | 78 | 86 | logging.warning("Audio not present") | 79 | 87 |
| 80 | 88 | try: | | 89 | + logging.info("starting camera") | 81 | 90 | cam = Camera.get_instance() | 82 | 91 | Motion.get_instance() | 83 | 92 | except picamera.exc.PiCameraError: | @@ -97,12 +106,12 @@ def run_server(): | 97 | 106 |
| 98 | 107 | remove_doreset_file() | 99 | 108 |
| 100 | | - app.run(host="0.0.0.0", port=5000, debug=False, use_reloader=False, threaded=True) | | 109 | + app.run(host="0.0.0.0", port=5000) | 101 | 110 | finally: | 102 | 111 | if cam: | 103 | 112 | cam.exit() | 104 | 113 | if bot: | 105 | 114 | bot.exit() | 106 | 115 |
| 107 | 116 | if __name__ == "__main__": | 108 | | - run_server() | | 117 | + run_server() |
Collapse file Copy file name to clipboardExpand all lines: coderbot/program.py +7-6Lines changed: 7 additions & 6 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -87,12 +87,13 @@ def __init__(self): | 87 | 87 | for filename in filenames: | 88 | 88 | if PROGRAM_PREFIX in filename: | 89 | 89 | program_name = filename[len(PROGRAM_PREFIX):-len(PROGRAM_SUFFIX)] | 90 | | - logging.info("adding program %s in path %s as default %r", program_name, dirname, ("default" in dirname)) | 91 | | - with open(os.path.join(dirname, filename), "r") as f: | 92 | | - program_dict = json.load(f) | 93 | | - program_dict["default"] = "default" in dirname | 94 | | - program = Program.from_dict(program_dict) | 95 | | - self.save(program) | | 90 | + if self._programs.search(query.name == program_name) == []: | | 91 | + logging.info("adding program %s in path %s as default %r", program_name, dirname, ("default" in dirname)) | | 92 | + with open(os.path.join(dirname, filename), "r") as f: | | 93 | + program_dict = json.load(f) | | 94 | + program_dict["default"] = "default" in dirname | | 95 | + program = Program.from_dict(program_dict) | | 96 | + self.save(program) | 96 | 97 |
| 97 | 98 | @classmethod | 98 | 99 | def get_instance(cls): | |
Collapse file Copy file name to clipboardExpand all lines: coderbot/v1.yml +43-3Lines changed: 43 additions & 3 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -170,6 +170,10 @@ paths: | 170 | 170 | required: true | 171 | 171 | schema: | 172 | 172 | type: string | | 173 | + minLength: 1 | | 174 | + maxLength: 128 | | 175 | + pattern: '^[a-zA-ZA-zÀ-ú0-9-_ ]+$' | | 176 | + | 173 | 177 | tags: | 174 | 178 | - Program management | 175 | 179 | responses: | @@ -184,6 +188,9 @@ paths: | 184 | 188 | required: true | 185 | 189 | schema: | 186 | 190 | type: string | | 191 | + minLength: 1 | | 192 | + maxLength: 128 | | 193 | + pattern: '^[a-zA-ZA-zÀ-ú0-9-_ ]+$' | 187 | 194 | responses: | 188 | 195 | 200: | 189 | 196 | description: "ok" | @@ -200,6 +207,9 @@ paths: | 200 | 207 | required: true | 201 | 208 | schema: | 202 | 209 | type: string | | 210 | + minLength: 1 | | 211 | + maxLength: 128 | | 212 | + pattern: '^[a-zA-ZA-zÀ-ú0-9-_ ]+$' | 203 | 213 | requestBody: | 204 | 214 | description: Program object | 205 | 215 | required: true | @@ -225,6 +235,9 @@ paths: | 225 | 235 | required: true | 226 | 236 | schema: | 227 | 237 | type: string | | 238 | + minLength: 1 | | 239 | + maxLength: 128 | | 240 | + pattern: '^[a-zA-ZA-zÀ-ú0-9-_ ]+$' | 228 | 241 | requestBody: | 229 | 242 | description: Program object | 230 | 243 | required: true | @@ -248,6 +261,9 @@ paths: | 248 | 261 | required: true | 249 | 262 | schema: | 250 | 263 | type: string | | 264 | + minLength: 1 | | 265 | + maxLength: 128 | | 266 | + pattern: '^[a-zA-ZA-zÀ-ú0-9-_ ]+$' | 251 | 267 | responses: | 252 | 268 | 200: | 253 | 269 | description: "ok" | @@ -264,6 +280,9 @@ paths: | 264 | 280 | required: true | 265 | 281 | schema: | 266 | 282 | type: string | | 283 | + minLength: 1 | | 284 | + maxLength: 128 | | 285 | + pattern: '^[a-zA-ZA-zÀ-ú0-9-_ ]+$' | 267 | 286 | responses: | 268 | 287 | 200: | 269 | 288 | description: "ok" | @@ -304,6 +323,9 @@ paths: | 304 | 323 | required: true | 305 | 324 | schema: | 306 | 325 | type: string | | 326 | + minLength: 1 | | 327 | + maxLength: 128 | | 328 | + pattern: '^[a-zA-ZA-zÀ-ú0-9-_ ]+$' | 307 | 329 | - name: default | 308 | 330 | in: query | 309 | 331 | schema: | @@ -323,6 +345,9 @@ paths: | 323 | 345 | required: true | 324 | 346 | schema: | 325 | 347 | type: string | | 348 | + minLength: 1 | | 349 | + maxLength: 128 | | 350 | + pattern: '^[a-zA-ZA-zÀ-ú0-9-_ ]+$' | 326 | 351 | requestBody: | 327 | 352 | description: Update Activity | 328 | 353 | required: true | @@ -346,6 +371,9 @@ paths: | 346 | 371 | required: true | 347 | 372 | schema: | 348 | 373 | type: string | | 374 | + minLength: 1 | | 375 | + maxLength: 128 | | 376 | + pattern: '^[a-zA-ZA-zÀ-ú0-9-_ ]+$' | 349 | 377 | responses: | 350 | 378 | 200: | 351 | 379 | description: "ok" | @@ -386,6 +414,9 @@ paths: | 386 | 414 | required: true | 387 | 415 | schema: | 388 | 416 | type: string | | 417 | + minLength: 1 | | 418 | + maxLength: 128 | | 419 | + pattern: '^[a-zA-ZA-zÀ-ú0-9-_ ]+$' | 389 | 420 | tags: | 390 | 421 | - Music extensions | 391 | 422 | responses: | @@ -502,12 +533,13 @@ paths: | 502 | 533 | type: string | 503 | 534 | minLength: 1 | 504 | 535 | maxLength: 256 | | 536 | + pattern: '^[a-zA-ZA-zÀ-ú0-9-_ ]+$' | 505 | 537 | description: text to be "spoken" | 506 | 538 | locale: | 507 | 539 | type: string | 508 | 540 | minLength: 1 | 509 | 541 | maxLength: 2 | 510 | | - pattern: '^[a-zA-ZA-zÀ-ú0-9-_ ]+$' | | 542 | + pattern: '^[a-zA-Z]+$' | 511 | 543 | description: locale of text to be "spoken" | 512 | 544 | required: | 513 | 545 | - text | @@ -586,6 +618,9 @@ paths: | 586 | 618 | required: true | 587 | 619 | schema: | 588 | 620 | type: string | | 621 | + minLength: 1 | | 622 | + maxLength: 128 | | 623 | + pattern: '^[a-zA-ZA-zÀ-ú0-9-_ ]+$' | 589 | 624 | tags: | 590 | 625 | - CNN Models | 591 | 626 | responses: | @@ -600,6 +635,9 @@ paths: | 600 | 635 | required: true | 601 | 636 | schema: | 602 | 637 | type: string | | 638 | + minLength: 1 | | 639 | + maxLength: 128 | | 640 | + pattern: '^[a-zA-ZA-zÀ-ú0-9-_ ]+$' | 603 | 641 | tags: | 604 | 642 | - CNN Models | 605 | 643 | responses: | @@ -679,16 +717,17 @@ components: | 679 | 717 | properties: | 680 | 718 | name: | 681 | 719 | type: string | | 720 | + pattern: '^[a-zA-ZA-zÀ-ú0-9-_ ]+$' | 682 | 721 | tag: | 683 | 722 | type: string | 684 | 723 | Program: | 685 | 724 | type: object | 686 | 725 | properties: | 687 | 726 | name: | 688 | 727 | type: string | 689 | | - pattern: '^[a-zA-ZA-zÀ-ú0-9-_ ]+$' | 690 | 728 | minLength: 1 | 691 | 729 | maxLength: 128 | | 730 | + pattern: '^[a-zA-ZA-zÀ-ú0-9-_ ]+$' | 692 | 731 | code: | 693 | 732 | type: string | 694 | 733 | minLength: 1 | @@ -709,6 +748,7 @@ components: | 709 | 748 | type: string | 710 | 749 | minLength: 1 | 711 | 750 | maxLength: 128 | | 751 | + pattern: '^[a-zA-ZA-zÀ-ú0-9-_ ]+$' | 712 | 752 | description: | 713 | 753 | type: string | 714 | 754 | minLength: 0 | @@ -722,4 +762,4 @@ components: | 722 | 762 | - description | 723 | 763 | - default | 724 | 764 | - stock | 725 | | - | | 765 | + |
Collapse file Copy file name to clipboardExpand all lines: docker/stub/requirements.txt +1-4Lines changed: 1 addition & 4 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 1 | 1 | # API framework | 2 | | -connexion==2.14.2 | 3 | | -Flask==2.2.5 | 4 | | -Flask-Cors==3.0.10 | | 2 | +connexion[uvicorn,flask,swagger-ui]==3.0.5 | 5 | 3 | tinydb==4.8.0 | 6 | | -Werkzeug==2.2.3 | 7 | 4 |
| 8 | 5 | # Misc utils | 9 | 6 | setuptools==69.2.0 | |
Collapse file Copy file name to clipboardExpand all lines: docker/stub/start.sh +1-1Lines changed: 1 addition & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
| 2 | 2 |
| 3 | 3 | export PYTHONPATH=./stub:./test:./coderbot | 4 | 4 | cd /coderbot | 5 | | -python3 coderbot/main.py | | 5 | +python3 coderbot/main.py & python3 stub/wifi/main.py |
Collapse file Copy file name to clipboardExpand all lines: requirements.txt +1-4Lines changed: 1 addition & 4 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 1 | 1 | # API framework | 2 | | -connexion==2.14.2 | 3 | | -Flask==2.2.5 | 4 | | -Flask-Cors==3.0.10 | | 2 | +connexion[uvicorn,flask,swagger-ui]==3.0.5 | 5 | 3 | tinydb==4.8.0 | 6 | | -Werkzeug==2.2.3 | 7 | 4 |
| 8 | 5 | # Misc utils | 9 | 6 | setuptools==69.2.0 | |
Collapse file Copy file name to clipboard +19Lines changed: 19 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +import logging | | 2 | + | | 3 | +def list_access_points(): | | 4 | + return {"ssids": [{"ssid": "my_wifi"}]} | | 5 | + | | 6 | +def connection_status(): | | 7 | + return {"wifi": "true", "internet": "true"} | | 8 | + | | 9 | +def connect(): | | 10 | + return "ok" | | 11 | + | | 12 | +def forget(): | | 13 | + return "ok" | | 14 | + | | 15 | +def sset_hotspot_ssid(): | | 16 | + return "ok" | | 17 | + | | 18 | +def set_hotspot_password(): | | 19 | + return "ok" |
|