Files
desungongpai/app/main.py

101 lines
3.4 KiB
Python
Raw Normal View History

from pathlib import Path
from fastapi import FastAPI
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from contextlib import asynccontextmanager
from app.database import init_db, async_session
from app.tcp_server import tcp_manager
from app.config import settings
from app.routers import devices, locations, alarms, attendance, commands, bluetooth, beacons
import asyncio
import logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
@asynccontextmanager
async def lifespan(app: FastAPI):
# Startup
logger.info("Initializing database...")
await init_db()
# Reset all devices to offline on startup (stale state from previous run)
try:
from sqlalchemy import update
from app.models import Device
async with async_session() as session:
async with session.begin():
await session.execute(update(Device).values(status="offline"))
logger.info("All devices reset to offline on startup")
except Exception:
logger.exception("Failed to reset device statuses on startup")
logger.info("Starting TCP server on %s:%d", settings.TCP_HOST, settings.TCP_PORT)
tcp_task = asyncio.create_task(tcp_manager.start(settings.TCP_HOST, settings.TCP_PORT))
yield
# Shutdown
logger.info("Shutting down TCP server...")
await tcp_manager.stop()
tcp_task.cancel()
app = FastAPI(
title="KKS Badge Management System / KKS工牌管理系统",
description="""
## KKS P240 & P241 蓝牙工牌管理后台
### 功能模块 / Features:
- **设备管理 / Device Management** - 设备注册状态监控
- **位置数据 / Location Data** - GPS/LBS/WIFI定位数据查询与轨迹回放
- **报警管理 / Alarm Management** - SOS围栏低电等报警处理
- **考勤管理 / Attendance** - 打卡记录查询与统计
- **指令管理 / Commands** - 远程指令下发与留言
- **蓝牙数据 / Bluetooth** - 蓝牙打卡与定位数据
- **信标管理 / Beacons** - 蓝牙信标注册与位置配置
### 通讯协议 / Protocol:
- TCP端口: {tcp_port} (设备连接)
- 支持协议: KKS P240/P241 通讯协议
""".format(tcp_port=settings.TCP_PORT),
version="1.0.0",
docs_url="/docs",
redoc_url="/redoc",
lifespan=lifespan,
)
# Include routers
app.include_router(devices.router)
app.include_router(locations.router)
app.include_router(alarms.router)
app.include_router(attendance.router)
app.include_router(commands.router)
app.include_router(bluetooth.router)
app.include_router(beacons.router)
_STATIC_DIR = Path(__file__).parent / "static"
app.mount("/static", StaticFiles(directory=str(_STATIC_DIR)), name="static")
@app.get("/admin", response_class=HTMLResponse, tags=["Admin"])
async def admin_page():
"""管理后台页面 / Admin Dashboard"""
html_path = _STATIC_DIR / "admin.html"
return HTMLResponse(content=html_path.read_text(encoding="utf-8"))
@app.get("/", tags=["Root"])
async def root():
return {
"name": settings.APP_NAME,
"version": "1.0.0",
"docs": "/docs",
"redoc": "/redoc",
"admin": "/admin",
"tcp_port": settings.TCP_PORT,
}
@app.get("/health", tags=["Root"])
async def health():
return {
"status": "healthy",
"connected_devices": len(tcp_manager.connections),
}