Skip to content

Commit

Permalink
🚧 ⚗️ #1 Connecting web and python, work in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
Balaji-Ganesh committed Jun 15, 2023
1 parent 2b419f1 commit 87d32fc
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 33 deletions.
57 changes: 55 additions & 2 deletions middleware/communication/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This file is from the branch `experiments` as `fastapi_as_api_in_class.py`
import asyncio
from fastapi import FastAPI, APIRouter
from fastapi import APIRouter, WebSocket, WebSocketDisconnect
import cv2

# Get the helpers..
Expand All @@ -23,13 +23,33 @@ def __init__(self, esp32IP: str, cam_port: int = 81, data_port: int = 82):
self.cam_task = None
self.data_task = None

self.cam_ws = None
self.data_ws = None

self.task = None
self.router = APIRouter()

@self.router.get("/")
async def read_root():
return {"Hello": "World"}

@self.router.get("/connection/{function}")
async def camera_feed_handler(function: str):
if function == 'establish':
if self.cam_ws is None and self.data_ws is None:
# asyncio.create_task(esp32._connection_establisher(self))
await esp32._connection_establisher(self)
return {"message": "Connection to ESP32 established."}
else:
return {"message": "Connections already established."}
elif function == 'terminate':
if self.cam_ws is not None and self.data_ws is not None:
# asyncio.create_task(esp32._connection_establisher(self))
await esp32._connection_terminater(self)
return {"message": "Connection to ESP32 terminated."}
else:
return {"message": "Connections already terminated."}

@self.router.get("/camera-feed/{function}")
async def camera_feed_handler(function: str):
if function == 'start':
Expand Down Expand Up @@ -73,7 +93,27 @@ async def collision_dist_handler(function: str):
else:
return {"message": "No collision-data task is currently running."}



class ConnectionManager:
def __init__(self):
self.active_connections: list[WebSocket] = []

async def connect(self, websocket: WebSocket):
await websocket.accept()
self.active_connections.append(websocket)

def disconnect(self, websocket: WebSocket):
self.active_connections.remove(websocket)

async def send_personal_message(self, message: str, websocket: WebSocket):
await websocket.send_text(message)

async def broadcast(self, message: str):
for connection in self.active_connections:
await connection.send_text(message)

manager = ConnectionManager()

class WebManager:
"""Manages all the connections to the web-app.
"""
Expand All @@ -83,3 +123,16 @@ def __init__(self):
@self.router.get('/web')
def sayhello():
return 'Hello Web app'

@self.router.websocket("/web/text")
async def websocket_endpoint(websocket: WebSocket):
await manager.connect(websocket)

try:
while True:
# data = await websocket.receive_text()
await manager.send_personal_message("You wrote: Hello Rama..!!", websocket)
# await manager.broadcast("Client #123 says: How are you Rama?")
except WebSocketDisconnect:
manager.disconnect(websocket)
await manager.broadcast("Client #123 left the chat")
33 changes: 30 additions & 3 deletions middleware/communication/esp32.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,38 @@
# The below functions will become data members of ESP32Manager in __init__.py


async def _connection_establisher(self):
try:
self.cam_ws = await websockets.connect(self.camera_ws_url)
self.data_ws = await websockets.connect(self.data_ws_url)
except Exception as e:
logging.error(
"[EXCEPTION] Connection establishment failed. Error: ", e)
finally:
logging.debug("Connection establishment done.")
return 'ERROR in connection establishment'


async def _connection_terminater(self):
try:
# Close the connection
await self.cam_ws.close()
await self.data_ws.close()
# Empty the connection holders
self.cam_ws, self.data_ws = None, None
except Exception as e:
logging.error(
"[EXCEPTION] Connection termination failed. Error: ", e)
finally:
logging.debug("Connection termination done.")
return 'ERROR in connection termination'


async def _camera_client(self):
try:
cam_ws = await websockets.connect(self.camera_ws_url)
# self.cam_ws = await websockets.connect(self.camera_ws_url)
while True:
msg = await cam_ws.recv()
msg = await self.cam_ws.recv()
# even try with msg.data
npimg = np.array(bytearray(msg), dtype=np.uint8)
img = cv2.imdecode(npimg, -1)
Expand All @@ -23,7 +50,7 @@ async def _camera_client(self):
logging.error(
"[EXCEPTION] Camera streaming interrupted. Error: ", e)
finally:
await cam_ws.close()
await self.cam_ws.close()
logging.debug("Camera Websockets Connection closed successfully")
return 'ERROR in fetching feed'

Expand Down
4 changes: 2 additions & 2 deletions middleware/main.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# This file is from the branch `experiments` as `fastapi_as_api_in_class.py`
from fastapi import FastAPI, APIRouter
from communication import ESP32Manager, WebManager

import uvicorn
app = FastAPI()
esp32 = ESP32Manager(esp32IP='192.168.134.165')
web = WebManager()
Expand All @@ -10,4 +10,4 @@
app.include_router(web.router)

# if __name__ == "__main__":
# uvicorn.run(app, host="127.0.0.2", port=8000, reload=True)
# uvicorn.run(app, host="127.0.0.2", port=8500)
65 changes: 39 additions & 26 deletions web/templates/manualMode.htm
Original file line number Diff line number Diff line change
Expand Up @@ -175,36 +175,49 @@ <h1>Manual Mode</h1>

{% block socketio_connection %}
<script type="text/javascript" charset="utf-8">
const socket = io.connect('http://127.0.0.1:5000'); // url of the python server, later use namespace/room specific to mode
// const socket = io.connect('http://127.0.0.1:5000'); // url of the python server, later use namespace/room specific to mode

socket.on('connect', function(){
socket.emit('ack', {
msg: 'CONN_ESTABLISHED'
});
console.log('Connected to server')
});
// socket.on('connect', function(){
// socket.emit('ack', {
// msg: 'CONN_ESTABLISHED'
// });
// console.log('Connected to server')
// });

socket.on('disconnect', function(){
console.log("Disconnecting with the server")
socket.emit('ack', {
msg: 'CONN_TERMINATED'
});
})
// socket.on('disconnect', function(){
// console.log("Disconnecting with the server")
// socket.emit('ack', {
// msg: 'CONN_TERMINATED'
// });
// })

socket.on('json', (data)=>{
console.log('server replied: ', data)
})
// socket.on('json', (data)=>{
// console.log('server replied: ', data)
// })

if(confirm("Start streaming?") == true){
console.log('streaming begins...')
socket.emit('stream', {msg: 'start streaming'})
// if(confirm("Start streaming?") == true){
// console.log('streaming begins...')
// socket.emit('stream', {msg: 'start streaming'})
// }
// socket.on('img_data', function(msg){
// console.log("Image received")
// const img_element = document.getElementById("cam_img")
// console.log(typeof(img_element))
// console.log(img_element)
// img_element.src="data:image/jpeg;base64,"+msg;
// })
const socket = new WebSocket('ws://127.0.0.2:8500/web/text')

socket.onopen = ()=>{
console.log("Websocket connection established")
}

socket.onclose = ()=>{
console.log("Websocket connection terminated")
}

socket.onmessage = (event)=>{
console.log(event.data)
}
socket.on('img_data', function(msg){
console.log("Image received")
const img_element = document.getElementById("cam_img")
console.log(typeof(img_element))
console.log(img_element)
img_element.src="data:image/jpeg;base64,"+msg;
})
</script>
{% endblock %}

0 comments on commit 87d32fc

Please sign in to comment.