You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现Angular与Python应用对接以展示CAN总线采集数据?

直接实现Angular与Python数据交互的方案

针对你的需求,最直接的方式是给Python应用添加轻量级的API接口或WebSocket服务,让Angular可以直接请求/接收数据,完全不需要文件或数据库,以下是两种落地性极强的方案:

方案一:HTTP轮询(适配10秒间隔需求)

用FastAPI或Flask搭建极简HTTP服务器,暴露接口返回最新CAN总线数据,Angular每10秒发起一次请求获取数据。

Python端实现(FastAPI示例)

  1. 安装依赖:
pip install fastapi uvicorn python-can
  1. 编写采集+接口代码(main.py):
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
import can
import threading
import time

# 初始化FastAPI应用
app = FastAPI()

# 解决跨域问题(生产环境请替换为你的Angular域名)
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# 存储最新CAN数据
current_can_data = {"temperature": 0.0, "weight": 0.0}

def can_data_collector():
    # 初始化CAN总线(根据硬件调整channel、bustype等参数)
    bus = can.interface.Bus(channel='can0', bustype='socketcan')
    while True:
        msg = bus.recv()
        # 替换为你的实际CAN消息解析逻辑
        if msg.arbitration_id == 0x100:
            current_can_data["temperature"] = float(msg.data[0]) + float(msg.data[1])/100
        elif msg.arbitration_id == 0x101:
            current_can_data["weight"] = int.from_bytes(msg.data, byteorder='little') / 10
        time.sleep(0.1)

# 启动CAN采集后台线程
threading.Thread(target=can_data_collector, daemon=True).start()

# 暴露接口返回最新数据
@app.get("/api/can-data")
async def get_latest_can_data():
    return current_can_data
  1. 启动服务:
uvicorn main:app --host 0.0.0.0 --port 8000

Angular端实现

  1. 在AppModule中导入HttpClientModule:
import { HttpClientModule } from '@angular/common/http';

@NgModule({
  imports: [HttpClientModule],
  // ...其他配置
})
export class AppModule { }
  1. 创建数据服务(can-data.service.ts):
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { interval } from 'rxjs';
import { switchMap } from 'rxjs/operators';

@Injectable({ providedIn: 'root' })
export class CanDataService {
  private apiUrl = 'http://你的Python服务器IP:8000/api/can-data';

  constructor(private http: HttpClient) {}

  // 每10秒获取一次数据
  getCanDataPeriodically() {
    return interval(10000).pipe(
      switchMap(() => this.http.get(this.apiUrl))
    );
  }
}
  1. 在表格组件中使用:
import { Component, OnInit } from '@angular/core';
import { CanDataService } from './can-data.service';

@Component({
  selector: 'app-data-table',
  template: `
    <table border="1">
      <tr>
        <th>温度</th>
        <th>重量</th>
      </tr>
      <tr>
        <td>{{ latestData?.temperature.toFixed(2) }} °C</td>
        <td>{{ latestData?.weight.toFixed(2) }} kg</td>
      </tr>
    </table>
  `
})
export class DataTableComponent implements OnInit {
  latestData: any;

  constructor(private canDataService: CanDataService) {}

  ngOnInit() {
    this.canDataService.getCanDataPeriodically().subscribe(data => {
      this.latestData = data;
    });
  }
}

方案二:WebSocket推送(适合实时性更高的场景)

如果CAN数据更新频繁,WebSocket可以让Python主动向Angular推送数据,避免不必要的轮询请求。

Python端实现(FastAPI WebSocket示例)

修改main.py,添加WebSocket端点:

from fastapi import WebSocket
import asyncio
# ...保留之前的CORSMiddleware、can_data_collector等代码

@app.websocket("/ws/can-data")
async def websocket_can_data(websocket: WebSocket):
    await websocket.accept()
    try:
        while True:
            await websocket.send_json(current_can_data)
            await asyncio.sleep(10)  # 每10秒推送一次
    except WebSocketDisconnect:
        pass

Angular端实现

  1. 创建WebSocket服务(can-ws.service.ts):
import { Injectable } from '@angular/core';
import { webSocket } from 'rxjs/webSocket';

@Injectable({ providedIn: 'root' })
export class CanWsService {
  private socket$ = webSocket('ws://你的Python服务器IP:8000/ws/can-data');

  listenForCanData() {
    return this.socket$.asObservable();
  }
}
  1. 在组件中使用:
import { Component, OnInit } from '@angular/core';
import { CanWsService } from './can-ws.service';

@Component({
  selector: 'app-data-table',
  template: `
    <table border="1">
      <tr>
        <th>温度</th>
        <th>重量</th>
      </tr>
      <tr>
        <td>{{ latestData?.temperature.toFixed(2) }} °C</td>
        <td>{{ latestData?.weight.toFixed(2) }} kg</td>
      </tr>
    </table>
  `
})
export class DataTableComponent implements OnInit {
  latestData: any;

  constructor(private wsService: CanWsService) {}

  ngOnInit() {
    this.wsService.listenForCanData().subscribe(data => {
      this.latestData = data;
    });
  }
}

方案选择

  • 若需求是固定10秒更新一次,HTTP轮询实现更简单,无需额外处理连接状态。
  • 若CAN数据变化频繁,且希望数据一更新就推送到前端,WebSocket更高效。

内容的提问来源于stack exchange,提问作者Michael

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 07:50:18