diff --git a/README.md b/README.md index 039c93f..8ae640c 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ A hub for controlling IOT devices. ## Requirements Python 3.6+ -Python packages: `gunicorn aiohttp aiohttp_jinja2 requests` +Python packages: `gunicorn aiohttp aiohttp_jinja2 uvloop requests` ## Install 1. Get on the floor diff --git a/events.py b/events.py index 2e2c7ab..c9305b9 100644 --- a/events.py +++ b/events.py @@ -6,7 +6,7 @@ import types import models from models import network -async def toggle_outlet(ws, data): +async def toggle_outlet(request, ws, data): """Toggles the state of a RelayDevice.""" device_id = data.get('device_id') sub_device_id = data.get('sub_device_id') @@ -32,10 +32,10 @@ async def toggle_outlet(ws, data): data['ok'] = True data['state'] = state res = {'event': 'toggle_outlet', 'data': data} - await ws.send_json(res) + await request.app.send_json_all(res) -async def edit_field(ws, data): +async def edit_field(request, ws, data): """Edits the text of a particular field.""" device_id = data.get('device_id') sub_device_id = data.get('sub_device_id') @@ -89,10 +89,10 @@ async def edit_field(ws, data): data['ok'] = True res = {'event': 'edit_field', 'data': data} - await ws.send_json(res) + await request.app.send_json_all(res) -async def new_device(ws, data): +async def new_device(request, ws, data): """ Allows adding a new device. Accepts device_type parameter, returns the device_id. @@ -127,10 +127,10 @@ async def new_device(ws, data): data['ok'] = True data['device_id'] = device.id res = {'event': 'new_device', 'data': data} - await ws.send_json(res) + await request.app.send_json_all(res) -async def lock_device(ws, data): +async def lock_device(request, ws, data): """Locks or unlocks a device to prevent or allow editing it's fields.""" device_id = data.get('device_id') locked = bool(data.get('locked')) @@ -151,10 +151,10 @@ async def lock_device(ws, data): data['ok'] = True res = {'event': 'lock_device', 'data': data} - await ws.send_json(res) + await request.app.send_json_all(res) -async def delete_device(ws, data): +async def delete_device(request, ws, data): """Deletes a device.""" device_id = data.get('device_id') @@ -173,7 +173,7 @@ async def delete_device(ws, data): data['ok'] = True res = {'event': 'delete_device', 'data': data} - await ws.send_json(res) + await request.app.send_json_all(res) events = {} diff --git a/juice.py b/juice.py index eb8f15a..014a3a4 100644 --- a/juice.py +++ b/juice.py @@ -45,6 +45,7 @@ async def websocket_handler(request): if not ws_ready.ok: return web.Response(text="Cannot start websocket.") await ws.prepare(request) + request.app['websockets'].append(ws) async for msg in ws: if msg.type != WSMsgType.TEXT: @@ -57,15 +58,24 @@ async def websocket_handler(request): event = data.get('event') if not event or event not in events.events.keys(): break - await events.events[event](ws, data.get('data')) + await events.events[event](request, ws, data.get('data')) await ws.close() + request.app['websockets'].remove(ws) return ws +async def send_json_all(self, d): + """Sends to all connected websockets.""" + for ws in self['websockets']: + await ws.send_json(d) + + async def init_app(): """Initializes the application.""" + web.Application.send_json_all = send_json_all app = web.Application(middlewares=[buckler_aiohttp.buckler_session]) aiohttp_jinja2.setup(app, loader=jinja2.FileSystemLoader('templates')) + app['websockets'] = [] app.router.add_routes(routes)