Merged changes from etienne and fixed conflicts

This commit is contained in:
AzureAD\AniketSaha 2025-07-08 15:21:52 +02:00
parent 174befca92
commit f39fcc9924
4 changed files with 68 additions and 3 deletions

19
dockerfile Normal file
View File

@ -0,0 +1,19 @@
# Dockerfile
FROM python:3.11-slim
WORKDIR /app
# Install required packages
RUN apt-get update && apt-get install -y \
iproute2 \
can-utils \
libpython3-dev \
&& rm -rf /var/lib/apt/lists/*
# Copy all application files
COPY . .
# Install Python dependencies
RUN pip install --no-cache-dir -r requirements.txt
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

29
main.py
View File

@ -2,6 +2,9 @@ from fastapi import FastAPI, HTTPException, Query
from fastapi.staticfiles import StaticFiles from fastapi.staticfiles import StaticFiles
from fastapi.responses import HTMLResponse from fastapi.responses import HTMLResponse
import logging import logging
import os
from fastapi import Request, APIRouter
import subprocess
import platform import platform
if platform.system() in ['Darwin']: # macOS or Windows if platform.system() in ['Darwin']: # macOS or Windows
from MockCAN import CANBackend from MockCAN import CANBackend
@ -9,13 +12,30 @@ else :
from classCAN import CANBackend # Your real backend from classCAN import CANBackend # Your real backend
app = FastAPI() app = FastAPI()
router = APIRouter()
logging.basicConfig(level=logging.INFO) logging.basicConfig(level=logging.INFO)
can_backend = CANBackend() can_backend = CANBackend()
# Serve static files (HTML, JS, CSS) # Serve static files (HTML, JS, CSS)
app.mount("/static", StaticFiles(directory="static"), name="static") app.mount("/static", StaticFiles(directory="static"), name="static")
@router.post("/webhook")
async def github_webhook(request: Request):
payload = await request.json()
print("[WEBHOOK] Received webhook:", payload.get("head_commit", {}).get("message"))
# Run update script (you can improve security here)
try:
script_path = os.path.join(os.path.dirname(__file__), "update_hmi.sh")
subprocess.run([script_path], check=True)
return {"status": "Update triggered"}
except subprocess.CalledProcessError as e:
return {"status": "Update failed", "error": str(e)}
@app.post("/connect_toggle") @app.post("/connect_toggle")
def connect_toggle(): def connect_toggle():
"""Toggle CAN connection.""" """Toggle CAN connection."""
@ -26,7 +46,7 @@ def connect_toggle():
else: else:
success = can_backend.connect( success = can_backend.connect(
node_id=0x02, node_id=0x02,
eds_path=r"/eds_file/processBoard_0.eds" eds_path = os.path.join(os.path.dirname(__file__), "eds_file", "processBoard_0.eds")
) )
if not success: if not success:
raise HTTPException(status_code=500, detail="Connection failed.") raise HTTPException(status_code=500, detail="Connection failed.")
@ -35,12 +55,14 @@ def connect_toggle():
@app.post("/command/{state}/pu/{pu_number}") @app.post("/command/{state}/pu/{pu_number}")
def send_command(state: str, pu_number: int, ploop_setpoint: float = Query(...)): def send_command(state: str, pu_number: int, ploop_setpoint: float = Query(...)):
"""Send a state command to a specific PU.""" """Send a state command to a specific PU."""
logging.info(f"Sending state '{state}' to PU {pu_number} with ploop_setpoint {ploop_setpoint}") logging.info(f"Sending state '{state}' to PU {pu_number}")
try: try:
can_backend.send_state_command(state.upper(), pu_number, ploop_setpoint) can_backend.send_state_command(state.upper(), pu_number, ploop_setpoint)
return {"status": "success", "command": state.upper(), "pu": pu_number, "ploop_setpoint": ploop_setpoint} return {"status": "success", "command": state.upper(), "pu": pu_number, "ploop_setpoint": ploop_setpoint}
except Exception as e: except Exception as e:
raise HTTPException(status_code=500, detail=str(e)) raise HTTPException(status_code=500, detail=str(e))
@app.get("/monitor") @app.get("/monitor")
def get_monitor_data(): def get_monitor_data():
data = can_backend.get_latest_data() data = can_backend.get_latest_data()
@ -52,7 +74,6 @@ def get_monitor_data():
"Pro": [0.0, 0.0, 0.0], "Pro": [0.0, 0.0, 0.0],
} }
@app.get("/can_status") @app.get("/can_status")
def can_status(): def can_status():
"""Return current CAN connection status.""" """Return current CAN connection status."""
@ -64,6 +85,8 @@ async def read_root():
with open("static/index.html", "r") as file: with open("static/index.html", "r") as file:
return HTMLResponse(content=file.read(), status_code=200) return HTMLResponse(content=file.read(), status_code=200)
app.include_router(router)
if __name__ == "__main__": if __name__ == "__main__":
import uvicorn import uvicorn
uvicorn.run( uvicorn.run(

4
requirements.txt Normal file
View File

@ -0,0 +1,4 @@
fastapi
uvicorn[standard]
python-can
canopen

19
update_hmi.sh Normal file
View File

@ -0,0 +1,19 @@
#!/bin/bash
echo "[UPDATE] Pulling latest changes (on host)..."
cd /home/hmi/Desktop/HMI || exit 1
git pull origin main || exit 1
echo "[UPDATE] Rebuilding Docker image..."
docker build -t hmi-app . || exit 1
echo "[UPDATE] Restarting container..."
docker stop hmi && docker rm hmi
docker run -d --name hmi \
--network host \
--privileged \
--restart unless-stopped \
-v /home/hmi/Desktop/HMI:/app \
hmi-app || exit 1
echo "[UPDATE] Complete"