Skip to content

Commit 4e0e1ec

Browse files
authored
cherry pick: fix coderbot init, program load (#203)
* fix init coderbot * fix program load * bump connexion to 3.0.x * add wifi stub
1 parent c437c0f commit 4e0e1ec

File tree

12 files changed

+204
-50
lines changed

12 files changed

+204
-50
lines changed

coderbot/api.py

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,7 @@
2727

2828
BUTTON_PIN = 16
2929

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()
4031
audio_device = Audio.get_instance()
4132
cam = Camera.get_instance()
4233

coderbot/audio.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
import pyaudio
2727
import alsaaudio
2828

29-
from six.moves import queue
29+
import queue
3030
# [END import_libraries]
3131

3232
# Audio recording parameters

coderbot/coderbot.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,10 @@ def exit(self):
157157
s.cancel()
158158

159159
@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):
161161
if not cls.the_bot:
162+
if from_defaults:
163+
raise ValueError("incorrect CoderBot initialisation")
162164
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)
163165
return cls.the_bot
164166

@@ -272,5 +274,4 @@ def _cb_button(self, gpio, level, tick):
272274
elif tick - self._cb_last_tick[gpio] > elapse:
273275
self._cb_last_tick[gpio] = tick
274276
logging.info("pushed: %d, %d", level, tick)
275-
cb()
276-
277+
cb()

coderbot/main.py

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
import picamera
99
import connexion
1010

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
1214

1315
from camera import Camera
1416
from motion import Motion
@@ -22,29 +24,27 @@
2224
# Logging configuration
2325
logger = logging.getLogger()
2426
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)
2927

3028
## (Connexion) Flask app configuration
3129

3230
# Serve a custom version of the swagger ui (Jinja2 templates) based on the default one
3331
# 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+
)
4242
app.prog_engine = ProgramEngine.get_instance()
4343

4444
## New API and web application
4545

4646
# 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')
4848

4949
def button_pushed():
5050
if app.bot_config.get('button_func') == "startstop":
@@ -67,8 +67,16 @@ def run_server():
6767
try:
6868
try:
6969
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)
7280

7381
try:
7482
audio_device = Audio.get_instance()
@@ -78,6 +86,7 @@ def run_server():
7886
logging.warning("Audio not present")
7987

8088
try:
89+
logging.info("starting camera")
8190
cam = Camera.get_instance()
8291
Motion.get_instance()
8392
except picamera.exc.PiCameraError:
@@ -97,12 +106,12 @@ def run_server():
97106

98107
remove_doreset_file()
99108

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)
101110
finally:
102111
if cam:
103112
cam.exit()
104113
if bot:
105114
bot.exit()
106115

107116
if __name__ == "__main__":
108-
run_server()
117+
run_server()

coderbot/program.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,13 @@ def __init__(self):
8787
for filename in filenames:
8888
if PROGRAM_PREFIX in filename:
8989
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)
9697

9798
@classmethod
9899
def get_instance(cls):

coderbot/v1.yml

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,10 @@ paths:
170170
required: true
171171
schema:
172172
type: string
173+
minLength: 1
174+
maxLength: 128
175+
pattern: '^[a-zA-ZA-zÀ-ú0-9-_ ]+$'
176+
173177
tags:
174178
- Program management
175179
responses:
@@ -184,6 +188,9 @@ paths:
184188
required: true
185189
schema:
186190
type: string
191+
minLength: 1
192+
maxLength: 128
193+
pattern: '^[a-zA-ZA-zÀ-ú0-9-_ ]+$'
187194
responses:
188195
200:
189196
description: "ok"
@@ -200,6 +207,9 @@ paths:
200207
required: true
201208
schema:
202209
type: string
210+
minLength: 1
211+
maxLength: 128
212+
pattern: '^[a-zA-ZA-zÀ-ú0-9-_ ]+$'
203213
requestBody:
204214
description: Program object
205215
required: true
@@ -225,6 +235,9 @@ paths:
225235
required: true
226236
schema:
227237
type: string
238+
minLength: 1
239+
maxLength: 128
240+
pattern: '^[a-zA-ZA-zÀ-ú0-9-_ ]+$'
228241
requestBody:
229242
description: Program object
230243
required: true
@@ -248,6 +261,9 @@ paths:
248261
required: true
249262
schema:
250263
type: string
264+
minLength: 1
265+
maxLength: 128
266+
pattern: '^[a-zA-ZA-zÀ-ú0-9-_ ]+$'
251267
responses:
252268
200:
253269
description: "ok"
@@ -264,6 +280,9 @@ paths:
264280
required: true
265281
schema:
266282
type: string
283+
minLength: 1
284+
maxLength: 128
285+
pattern: '^[a-zA-ZA-zÀ-ú0-9-_ ]+$'
267286
responses:
268287
200:
269288
description: "ok"
@@ -304,6 +323,9 @@ paths:
304323
required: true
305324
schema:
306325
type: string
326+
minLength: 1
327+
maxLength: 128
328+
pattern: '^[a-zA-ZA-zÀ-ú0-9-_ ]+$'
307329
- name: default
308330
in: query
309331
schema:
@@ -323,6 +345,9 @@ paths:
323345
required: true
324346
schema:
325347
type: string
348+
minLength: 1
349+
maxLength: 128
350+
pattern: '^[a-zA-ZA-zÀ-ú0-9-_ ]+$'
326351
requestBody:
327352
description: Update Activity
328353
required: true
@@ -346,6 +371,9 @@ paths:
346371
required: true
347372
schema:
348373
type: string
374+
minLength: 1
375+
maxLength: 128
376+
pattern: '^[a-zA-ZA-zÀ-ú0-9-_ ]+$'
349377
responses:
350378
200:
351379
description: "ok"
@@ -386,6 +414,9 @@ paths:
386414
required: true
387415
schema:
388416
type: string
417+
minLength: 1
418+
maxLength: 128
419+
pattern: '^[a-zA-ZA-zÀ-ú0-9-_ ]+$'
389420
tags:
390421
- Music extensions
391422
responses:
@@ -502,12 +533,13 @@ paths:
502533
type: string
503534
minLength: 1
504535
maxLength: 256
536+
pattern: '^[a-zA-ZA-zÀ-ú0-9-_ ]+$'
505537
description: text to be "spoken"
506538
locale:
507539
type: string
508540
minLength: 1
509541
maxLength: 2
510-
pattern: '^[a-zA-ZA-zÀ-ú0-9-_ ]+$'
542+
pattern: '^[a-zA-Z]+$'
511543
description: locale of text to be "spoken"
512544
required:
513545
- text
@@ -586,6 +618,9 @@ paths:
586618
required: true
587619
schema:
588620
type: string
621+
minLength: 1
622+
maxLength: 128
623+
pattern: '^[a-zA-ZA-zÀ-ú0-9-_ ]+$'
589624
tags:
590625
- CNN Models
591626
responses:
@@ -600,6 +635,9 @@ paths:
600635
required: true
601636
schema:
602637
type: string
638+
minLength: 1
639+
maxLength: 128
640+
pattern: '^[a-zA-ZA-zÀ-ú0-9-_ ]+$'
603641
tags:
604642
- CNN Models
605643
responses:
@@ -679,16 +717,17 @@ components:
679717
properties:
680718
name:
681719
type: string
720+
pattern: '^[a-zA-ZA-zÀ-ú0-9-_ ]+$'
682721
tag:
683722
type: string
684723
Program:
685724
type: object
686725
properties:
687726
name:
688727
type: string
689-
pattern: '^[a-zA-ZA-zÀ-ú0-9-_ ]+$'
690728
minLength: 1
691729
maxLength: 128
730+
pattern: '^[a-zA-ZA-zÀ-ú0-9-_ ]+$'
692731
code:
693732
type: string
694733
minLength: 1
@@ -709,6 +748,7 @@ components:
709748
type: string
710749
minLength: 1
711750
maxLength: 128
751+
pattern: '^[a-zA-ZA-zÀ-ú0-9-_ ]+$'
712752
description:
713753
type: string
714754
minLength: 0
@@ -722,4 +762,4 @@ components:
722762
- description
723763
- default
724764
- stock
725-
765+

docker/stub/requirements.txt

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
# 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
53
tinydb==4.8.0
6-
Werkzeug==2.2.3
74

85
# Misc utils
96
setuptools==69.2.0

docker/stub/start.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22

33
export PYTHONPATH=./stub:./test:./coderbot
44
cd /coderbot
5-
python3 coderbot/main.py
5+
python3 coderbot/main.py & python3 stub/wifi/main.py

requirements.txt

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
# 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
53
tinydb==4.8.0
6-
Werkzeug==2.2.3
74

85
# Misc utils
96
setuptools==69.2.0

stub/wifi/api.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
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"

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy