技术博客

27/03/2025 作者 Mattias Busck

关于CanKing 7 GUI扩展:创建与使用指南

什么是CanKing 7 GUI扩展?

CanKing 7 GUI扩展是 Kvaser CanKing中的图形视图。这些视图允许任何人使用其基于Web的组件扩展用户界面。用户可以通过创建按钮来发送报文,也可以通过创建各种网格和仪表来显示从CAN总线接收到的信息。

如何创建扩展

在CanKing中开发图形用户界面(GUI)扩展所使用的技术是React。React是用于构建用户界面的JavaScript库。通过使用网络技术,CanKing可以确保速度和安全性,而基于网络的应用程序(包括游戏)都有这两个要求。

CanKing API和React

文档

CanKing GUI扩展API定义了Kvaser特定组件。扩展程序可以使用这些组件发送和接收CAN报文,并实现与CanKing UI和服务的交互。

其他定义和概念(如钩子)来自React本身。对于学习React,https://react.dev/learn是一个很好的起点。

在阅读API文档和实施扩展时,了解这些概念非常重要。

打开Web浏览器窗口后,您可以在其中浏览API。

可用模块

API被划分为不同的模块。目前,这些模块包括控件、钩子、图标、IPC和模型。

控件

这些是作为React组件实现的UI控制组件的函数、类型和接口。例如CanIdentifierControl,它创建了一个用于编辑CAN标识符的UI控件。

钩子

该模块定义了React钩子。这些都是以“use”开头的函数(请参阅下文建议),可以在事件发生时为组件提供回调,也可以提供用于更新数据的函数。

useProjectData是一个重要的钩子 ,它允许扩展程序在CanKing项目(*.ckproj)文件中存储和加载其设置。

另一个钩子是useNewMeasurementData,它可以将CAN报文传递到扩展组件中,如跟踪窗口或可视仪表。

图标

该模块包含可用于CanKing UI的图标。

IPC

该模块实现了与CanKing服务交互的进程间通信(IPC)。例如:

- sendCanMessage(  
        channelId: string,  
        canId: number,  
        data: number[],  
        ...flags: [CanFrameFlag](../enums/models.CanFrameFlag.html)[],  
    ): Promise<void>

另一个函数是updateSource,它允许扩展程序更新CAN通道的属性,如总线参数。请注意,需要使用钩子useMeasurementSetup来更新当前的总线参数。

模型

模型模块包含类型、类、接口、枚举等。其中一个典型的例子就是useNewMeasurementData中的框架。

创建扩展

安装工具

为了开始使用,您需要CanKing 7和驱动程序。您还需要NodeJS和编辑器。Kvaser CanKing GUI Extensions SDK中的说明解释了细节。简而言之,您需要:

  1. Kvaser驱动程序
  2. CanKing 7
  3. NodeJS
  4. Visual Studio代码

使用Npm创建新扩展

  • 确保已安装NojeJS并将其放在命令行的PATH中。
  • 使用npm命令行创建扩展:npm create @kvaser/canking-extension@latest

(按回车键进行默认选择)

C:\Users\mabu\OneDrive - Kvaser AB\proj\CanKing-7-GUI-Extension-Guide>npm create @kvaser/canking-extension@latest

> npx
> create-extension

√ Project name: ... my-ck-extension
√ Package name: ... my-ck-extension
√ Display name: ... MyCkExtension
√ Package description: ... A CanKing GUI extension
√ Package author: ... Kvaser FAE

Creating a new CanKing extension in C:\Users\mabu\OneDrive - Kvaser AB\proj\CanKing-7-GUI-Extension-Guide\my-ck-extensi
on.


A project for extension my-ck-extension has been created successfully.

npm现在已经创建了一个名为my-ck-extension(选定的项目名称)的目录结构。我们进入该目录。

cd my-ck-extension

使用版本控件

在该目录中,已经创建了许多文件。为了跟踪更改,让我们使用git将它们添加到源代码控件中。

git init
git add .
git commit -m "Create CanKing7 extension from template"

安装依赖项

由于我们的扩展使用了NodeJS,因此需要安装扩展使用的软件包。在my-ck-extension目录中,使用:

npm install

这将在名为node_modules的新目录中安装所有必要的软件包。

运行扩展

加载代码

从扩展文件夹中使用shell命令启动VS Code:

  code .

启动/调试扩展

  • 如果已经安装了扩展,可以从Visual Studio Code开始调试:
  • 也可以使用终端:
npm run start

在CanKing中添加扩展

稍等片刻后,CanKing 7将启动,新扩展将出现在工作区的“选择视图”菜单中:

在工作区中,会出现一个显示扩展的新视图:

检查源

React

CanKing 7使用TypeScript,这是Javascript的静态类型超集,增加了类型定义。

请注意,由于React教程可以使用JavaScript或TypeScript,因此请确保使用需要说明变量类型的TypeScript版本。

Javascript、Typescript和XML

为了查看扩展,我们将开始检查文件src / WorkspaceView / index.tsx

my-ck-extension
└───src
    └───WorkspaceView
        └───index.tsx

这个文件的扩展名是“.tsx”,我们由此得出:

  • t表示这是TypeScriptJavascript的静态类型超集,增加了类型定义。
  • x表示这是JavaScript的类似XML的语法扩展。

有了类型定义,就能及早防止错误,并允许代码编辑器查找数据结构。例如,接口IProjectData定义了我们扩展中的哪些数据会保存在CanKing 7项目文件中。我们在此说明,参数channelId必须是字符串类型。

// If any data should be stored in the project file then add it to this interface
interface IProjectData {
  // This is an example showing how to store the selected channel id to the project file
  channelId: string;
}

WorkspaceView函数

我们的Index.tsx通过定义名为WorkspaceView的函数实现了CanKing 7的扩展。该函数首先以标准方式定义变量:

function WorkspaceView() {
  // Get this view's unique id from search params
  const [searchParams] = useSearchParams();
  const idString = searchParams.get('id');

在函数结束时,我们返回定义React组件的数据结构。通过语法扩展,我们可以直接编写XML结构。

大括号(如{icon}中的大括号)允许我们在其中嵌入使用变量的表达式。我们正在使用文件顶部的图标:

import icon from '../assets/icon.png';

我们可以看到,扩展包含一个位于顶层的方框组件:

    return (
        <Box aria-label="canking-extension-view" margin={1}>
            <h3>Add your elements here!</h3>
            <div>This is an example how to embed an image:</div>
            <img src={icon} height={50} />

发送CAN报文

要发送消息,首先需要导入一个按钮。

import { Box, Button } from '@mui/material';

然后将其添加到WorkspaceView函数中,并将其onClickprop设置为onSendCanMessage

<Button onClick={onSendCanMessage}> Send CAN Message </Button>

回调函数onSendCanMessage是通过React钩子useCallback创建的。

// A callback that will send out a CAN message on the selected channel with the specified CAN id
  const onSendCanMessage = useCallback(() => {
    if (projectData.channelId !== '') {
      const flags =
        sessionData.canIdType === 'extended' ? CanFrameFlag.CAN_FRAME_FLAG_EXT : CanFrameFlag.CAN_FRAME_FLAG_STD;
      sendCanMessage(projectData.channelId, sessionData.canId, [0x55], flags);
    }
  }, [projectData.channelId, sessionData.canId, sessionData.canIdType]);

原因在于,sendCanMessage需要访问channelId(字符串),以便通知CanKing 7服务在哪个通道上发送。建议将该字符串存储在projectData中。扩展中的所有组件都可以使用这个字符串,因为它是在顶层定义的。它也与.ckproj文件一起保存和加载。

// Use the useProjectData hook to serialize/deserialize your view data to the project
const { projectData, setProjectData } = useProjectData<IProjectData>(id, defaultProjectData);

要设置channelId,可以添加CanChannelSelectControl。其也由CanKing 7 SDK提供。为使其正常工作,该组件需要:

  1. 在创建时知道要显示哪个选项。
  2. 根据选项的变化采取行动,并将选项存储在自身之外。

为此,SDK定义了接口CanChannelSelectControlProps,允许将配置参数传递给控件。

(根据React惯例,接口的名称是组件名称 + Props)。

除其他参数外,onChannelIdentifierChange属性还接受用户选择CAN通道时将调用的回调函数。它还可以通过channelIdentifier获取初始值。

<CanChannelSelectControl
    channelIdentifier={projectData.channelId}
    onChannelIdentifierChange={onChannelIdentifierChange}
    hideSectionControl
  />

onChannelIdentifierChange回调函数定义如下:

  // A callback that will get the new selected channel id and save it to the project data
  const onChannelIdentifierChange = useCallback(
    (channelId: string) => {
      const data = { ...projectData };
      data.channelId = channelId;
      setProjectData(data);
    },
    [projectData, setProjectData],
  );

至此,对新扩展特性的初步检查就结束了。

Author Image

Mattias Busck