# mPy - esp32 server_http_ws template
#       Toggle Leds on button press on FSK0001
# Copyright by Anthony Vogelaar, Perth Scotland
# revision 0.10  2025-11-29  initial release

# For browser control:
#    connect to Wifi ssid : Esp32_AP  with password 12345678
#    in browser open      : http://192.168.4.1:5000

# for a new project edit:
#    domain.py
#    static/index.html
#    static/index.css
#    static/index.js
# use as is:
#    main.py, mve_wifi.py
#    static/ws.js
#    microdot/*

from	machine				import	freq;			freq(240_000_000)
from	mve_wifi_ap			import	startWifiAP;	startWifiAP()
import	asyncio
import	json
from	microdot			import	Microdot, send_file
from	microdot.websocket	import	with_websocket
from	domain				import	Domain

# sse: https://itsfuad.medium.com/understanding-server-sent-events-sse-with-node-js-3e881c533081

# ==================== webserver ========================

app 	   = Microdot()
websockets = set()
domain     = Domain()


# serve home page
@app.route('/')
async def index(request):
    return send_file('static/index.html')


# serve other static files
@app.route('static/<path:path>')
async def static(request, path):
    if '..' in path:
        return 'Not found', 404		# directory traversal not allowed
    return send_file(f'static/{path}')


# handle websockets and incoming data
@app.route('/ws')
@with_websocket
async def onWs(request, ws):
    websockets.add(ws)			# add to active websockets
    try:
        while True:
            obj = json.loads(await ws.receive())		
            if resp := domain.doCommand(obj):
                await wsBroadcast(resp)
    except: print('webServer.onWs: exception')
    websockets.remove(ws)		# remove from active websockets


# send obj to all connected websockets
async def wsBroadcast(obj):
    for ws in websockets:
        await ws.send(json.dumps(obj))

# ======================== main =========================

async def main():
    asyncio.create_task(app.start_server(debug=True))	# start web server
    while True:
        if resp := domain.exe():                 
            await wsBroadcast(resp)						# send to all connected websockets
        await asyncio.sleep(0)
        
        
asyncio.run(main())

# ========================= end =========================
