开发者中心

插件Web SDK

概述

在下面的文档中,您将看到插件Web SDK概述,它允许您

  • 扩展应用程序与自己的插件。
  • 将您自己的应用程序添加到QuarkIoE的Web应用程序。
  • 使用自定义小部件增强数据的可视化。
  • 实现为您的用例量身定制的功能。
结构

上图显示了应用程序和插件开发背后的结构。与核心应用程序相同,您的应用程序将基于AngularJS以及"c8y.core"和"c8y.ui"JavaScript API构建。两个模块都提供与QuarkIoE Web应用程序交互的服务。虽然模块"c8y.core"提供访问不同类型的数据(例如用户和托管对象)以及基本功能的服务,但模块"c8y.ui"提供了修改应用程序或插件的用户界面的服务,例如添加菜单项或小部件。模块依次使用QuarkIoE提供的REST API。您可以在插件示例中找到有关如何使用服务的示例。

首先,本文档描述了应用程序和插件背后的概念。然后它指定所需的文件夹结构和应用程序和插件的不同配置选项。随后,描述了开发应用程序和插件所需的设置。 Web SDK for Plugins指南的结构如下:

之后,我们将介绍如何逐步创建示例插件:

您还可以在以下文档中找到其他更复杂的示例:

虽然本章将介绍应用程序和插件概念的概述,但我们建议您看一下在开发应用程序中描述的QuarkIoE应用程序的基本概念。

概念

在构建应用程序或插件之前,了解应用程序和插件是什么很重要。 在这种情况下,应用程序基于QuarkIoE UI框架并组成QuarkIoE UI。 默认情况下,QuarkIoE UI由三个核心应用程序组成,即"设备管理","系统管理"和"控制台"。 反过来,应用程序包括插件。 插件代表您要添加到应用程序的任何功能。 有了插件,你可以:

  • 修改品牌形象,
  • 将新的导航项添加到菜单,
  • 添加新的小部件到仪表盘,
  • 添加新的菜单项到下拉菜单,
  • 添加新的视图或选项卡到群组和设备
  • 或任何想要集成进的其他功能 (例如搜索)。

这在下面说明:

插件扩展点

或者,作为示例,让我们看看"控制台"应用程序使用的插件列表的摘要。 特别是包括

  • 控制台首页:一个插件,将"首页"菜单添加到导航器。
  • 仪表盘:一个插件,它为组和设备添加了一个新的视图/选项卡,作为窗口小部件的容器。
  • 数据点表:一个插件,它向仪表板添加一个小部件,以表格形式提供测量的可视化。
  • 等等。

注意你能用新功能扩展QuarkIoE的核心应用程序(系统管理, 控制台, 设备管理)。对于普通租户,必须先创建核心应用程序的副本,然后才能扩展它。 要创建应用程序的副本,您可以通过UI在"系统管理"中复制创建使用与所需应用程序完全相同的插件的新应用程序

项目结构

无论何时创建新的应用程序或插件,您都必须遵守以下文件夹结构。 否则应用程序或插件将无法工作。 应用程序的默认文件夹结构如下 :


  <<根文件夹>>
    ├── cumulocity.json
    |    ...
    └── plugins
    └── <<插件名称>>
    ├── cumulocity.json
    └── index.js
    ...
                        

在应用程序的根文件夹中,所谓的"应用程序清单"存储在"cumulocity.json"文件中。 文件夹"plugins"中每个插件一个文件夹。 插件文件夹名称和应用程序名称唯一标识插件。 在每个插件文件夹中,所谓的"插件清单"存储在另一个"cumulocity.json"文件中。 应用程序清单和插件清单的格式如所述。 如果您只想创建一个插件并将其添加到已经存在的应用程序,请使用上述的文件夹结构


    <<根文件夹>>
    └── <<插件名称>
    ├── cumulocity.json
    └── index.js
    ...
                        
清单
应用程序清单

应用程序清单描述您的应用程序存储在何处以及如何将其暴露给QuarkIoE。可以使用以下属性:

  • name:应用程序的描述性名称。它会显示在应用应用程序切换器菜单中。
  • availability:"PRIVATE",如果应用程序只在您的租户中可用,"MARKET",如果它是公共应用程序。
  • contextPath:用于托管应用程序的路径。应用程序的网址为"<<yourURL>>/apps/<<contextPath>>"。
  • key:用于将应用程序的请求与应用程序关联和订阅应用程序的应用程序密钥。
  • resourcesUrl:如果应用程序正在提供上传zip文件(Smartapps是这种情况),此值将为"/"。如果它是一个完整的URL,所有的请求将代理到该地址。
  • type: HOSTED,如果应用程序通过QuarkIoE托管,EXTERNAL,如果应用程序托管在其他地方。
  • imports:应用程序使用的插件列表。 <<应用程序名称>>/<<插件名称>>列表。
  • noAppSwitcher:[可选]如果设置为true,应用程序将不会显示在应用程序切换器菜单中。一个可能的用例是,应用程序只暴露插件。
  • options:
    • hide_navigator:[可选]布尔值,如果设置为true,默认折叠左侧的导航器菜单。
    • globalTitle:[可选]将用作Web应用程序的全局标题。

注意,"contextPath"和"key"必须是唯一的。对于"PRIVATE"应用程序,属性"name"和"contextPath"只需要在您的租户内是唯一的。

插件清单

插件清单描述了插件在QuarkIoE系统管理应用程序(名称,描述,类别,图库,列表)中的显示方式,以及需要构建和加载哪些文件才能运行插件(ngModules, js, imports, css, less, copy)。

  • name: 插件的描述性名称,必需。
  • description: [可选]插件的详细说明。
  • category: [可选]用于在用户界面中过滤的插件的类别。
  • ngModules: 插件提供的AngularJS模块列表,至少需要一个。
  • js: [可选]要加载的JavaScript文件列表,如"index.js",控制器,服务,asf。路径是相对于插件的根文件夹。
  • css: [可选]要加载的CSS文件的列表,相对于插件根文件夹的路径。
  • less: [可选]要加载的LESS文件的列表,相对于插件根文件夹的路径。
  • copy: [可选]应复制到构建文件的文件列表。

清单文件的大部分内容对应于REST参考中描述的应用程序API属性。清单文件的示例可以在示例中找到。

设置

前提条件

插件基于HTML5。 您应该熟悉以下技术:

您将需要以下前提条件才能开发插件和执行示例:

您需要Node.js (6.7或更高版本) 您需要npm(与Node.js一起安装) *您需要能够访问您的QuarkIoE帐户,即您需要您的租户名称,用户名和密码。

QuarkIoE CLI工具

一旦所有前提条件都满足,你准备去构建自己的应用程序和插件。 对于开发插件(构建,主题,翻译和部署您的应用程序和插件)的过程,您需要在您的计算机上全局安装npm软件包"cumulocity-tools"。 要安装npm包,请在终端上执行以下命令。


  $ npm i cumulocity-tools -g
                      

现在您可以使用命令行界面(CLI)工具。 尝试通过执行以下命令:


  $ c8y --help
                      

"--help"选项显示CLI工具的所有可用命令。

QuarkIoE UI包

如上所述,应用程序总是插件的集合。 我们提供一组插件,你可以建立在除了你自己。 但在此之前,您必须添加一个"package.json"文件到您将用于您的应用程序的文件夹。 要自动生成"package.json"文件,只需运行:


  $ npm init
                      

请注意,此命令提示您输入将包括在"package.json"文件中的几个属性的值。 "package.json"文件应至少包括名称和版本。 要跳过属性,请按Enter键。

然后通过键入以下命令继续安装包含插件集的QuarkIoE UI程序包:


  $ c8y install latest
                      

此命令将:

  • 检查最新版本的QuarkIoE UI软件包。
  • 下载软件包。
  • 将其作为依赖项添加到"package.json"文件中。

而不是"最新",您还可以指定某个版本号,但此版本必须与后端版本号相同或小于后端版本号。

注意,当共享项目时,其他开发人员只需要在应用程序项目的根文件夹中运行npm install,因为QuarkIoE UI包的版本已经在"package.json"中定义为依赖项。你可以通过再次运行c8y install命令来安装其他版本。

您可以通过使用命令"c8y util:showimports [appContextPath]"查看应用程序使用的插件列表。

示例插件

设置完所有内容并深入了解文件夹结构和清单后,您可以开始构建您的第一个应用程序和插件。 下面的章节将告诉你如何让插件运行。 之后,你可以找到一个指南,建立一个"Hello World!"风格的插件。 您可以下载或克隆"Hello World!"。

运行示例

下载或克隆存储库库后,通过执行命令c8y deploy:app [appContextPath]创建包含您租户中示例插件的应用程序。 如果省略appContextPath,将从执行命令的路径上的"cumulocity.json"读取contextPath。

您将被要求提供租户的名称和基础URL,以及您的用户名和密码。 为了防止一次又一次地填写这些内容,您可以在计算机上定义以下环境变量:C8Y_TENANT, C8Y_USER, C8Y_PASSC8Y_BASE_URL

部署应用程序后,它将显示在"系统管理"应用程序的"我的应用程序"菜单中。

我的应用程序

想要看到"Hello world!"插件,导航到刚刚创建的示例,选择菜单"新建插件"。 你应该能够看到文本"Hello world!"。 您还可以尝试其他示例插件。 有关示例插件的更多信息,请参阅文档中的相应文档。

"Hello world!"

此插件的目的是向应用程序切换器菜单中添加一个新应用程序。 这个应用程序将包含一个单一的菜单项,将显示一个简单的"Hello world!"页面。 最后,应用程序应如下所示:

Hello world 插件

为了实现这一目标,需要执行以下步骤:

  • 创建一个应用程序项目。
  • 配置应用程序清单。
  • 在租户中注册应用程序。
  • 配置插件清单。
  • 实现插件的初始化函数以添加菜单项并将其与视图模板相关联。
  • 实现控制器为视图模板提供数据(以一个简单的文本为例)。
  • 添加视图模板以显示数据。
  • 测试应用程序。
  • 最后,构建并发布应用程序和插件。
创建应用程序项目

首先,我们需要通过创建应用程序项目

  • 创建一个任意名称的新文件夹。
  • 在此文件夹中创建一个"cumulocity.json"文件,代表我们的应用程序清单。
  • 运行命令"npm init"来创建一个新的"package.json"文件。
  • 运行命令"c8y install latest"获取最新的核心插件。

完成这些步骤后,您应该具有以下文件夹结构:


  <<根文件夹>>
  ├── node_modules
  |        └── ...
  ├── cumulocity.js
  └── package.json
                    
配置应用程序

其次,我们必须填写应用程序清单(我们的根文件夹中的"cumulocity.json"文件),其中包含有关QuarkIoE应用程序的信息,例如其名称,密钥,URL和依赖关系。 对于此示例,我们必须指定以下属性:

    
  {
    "availability": "PRIVATE",
    "contextPath": "myapplication",
    "key": "myapplication-appkey",
    "name": "myapplication",
    "resourcesUrl": "/",
    "type": "HOSTED",
    "imports": [
    "core/c8yBranding"
    ]
  }
                  

到目前为止的项目结构,已经可以测试我们的应用程序。 通过将QuarkIoE UI包中的"c8yBranding"插件添加到我们的导入中,我们的应用程序不会完全为空。 正如名称已经表明的,插件将Quarkioe的品牌形象添加到我们的应用程序。 在我们可以在本地测试应用程序之前,必须先在租户上创建它。

有关清单的其他属性的更多详细信息,请参阅"清单"。

在租户中创建应用程序

成功登录到QuarkIoE UI应用程序后,将自动提取应用程序密钥。 因此,为了开发应用程序,我们需要确保在我们的租户中创建应用程序。 要在我们的租户中创建应用程序,我们只需使用c8y deploy:app [appContextPath]部署它。 如果省略appContextPath,将从执行命令的路径上的"cumulocity.json"读取contextPath。


  $ c8y deploy:app myapplication
  ? Tenant piedpiper
  ? User admin
  ? Password ***********
  ? Base url https://piedpier.cumulocity.com
  GET application/applicationsByOwner/piedpier?pageSize=10000 200
  POST application/applications/31337/binaries/ 201
  PUT /application/applications/31337 200
                

您将被要求填写租户的名称和基础URL,以及您的用户名和密码。 为了防止一次又一次地填写这些内容,您可以在计算机上定义以下环境变量: C8Y_TENANT, C8Y_USER, C8Y_PASSC8Y_BASE_URL

注册后的应用程序会出现在QuarkIoE系统管理应用程序的 "我的应用程序" 菜单。

我的应用程序

测试应用程序

要在本地运行应用程序,只需运行c8y server。 你可以传递一个选项-u https://piedpier.cumulocity.com,表示api调用被代理到哪里。


  $ c8y server
  Quarkioe UI development server running in port 9000.
  Proxying api requests to https://bazinga.staging.c8y.io
  140 modules loaded.
  5 application manifest loaded.
  http://localhost:9000/apps/myapplication/ cumulocity.json
  http://localhost:9000/apps/fieldbus4/  Packaged App
  http://localhost:9000/apps/administration/  Packaged App
  http://localhost:9000/apps/cockpit/  Packaged App
  http://localhost:9000/apps/devicemanagement/  Packaged App
              

您可以通过在URL "http://localhost:9000/apps/myapplication/"打开浏览器来测试您的应用程序。如果您现在访问您的应用程序,您应该能够看到以下内容:

我的应用程序

现在缺少的是一个插件,它添加一个菜单项到导航器。

配置插件清单

每个插件都在应用程序的plugins文件夹中的一个单独的子文件夹。 所以要添加一个插件到我们的应用程序,我们必须

  • 在我们的项目中创建一个"plugins"文件夹
  • 在"plugins"文件夹中创建一个名为"myplugin"的文件夹。
  • 在"myplugin"文件夹中创建一个"cumulocity.json"文件,代表我们的应用程序清单。
  • 在"myplugin"文件夹中创建"views"文件夹。
  • 在"views"文件夹中创建一个"hello.html"文件,表示我们的插件的视图。

完成这些步骤后,您应该具有以下文件夹结构:


  <<根文件夹>>
    ├── node_modules
    ├── plugins
    |        └── hello
    |                ├──views
    |                |     └── hello.html
    |                └── cumulocity.json
    ├── cumulocity.js
    └── package.json
              

插件清单提供了有关我们插件的信息,例如名称,简短描述,要加载的文件和要添加到main应用程序的angular模块。 对于我们的示例,将以下行添加到"cumulocity.json"文件中:


  {
    "name": "Hello world plugin testing",
    "description": "Simple hello world plugin."
  }
            

有关清单的其他属性的更多详细信息,请参见"清单"。

现在我们已经为我们的应用程序添加了一个插件,我们还必须将它添加到我们的应用程序清单的导入中。 导入的名称由两个部分组成,以斜杠分隔。 第一部分必须是插件所在应用程序的上下文路径,第二部分必须是plugin文件夹的名称。 在我们的示例中,我们的插件位于我们的应用程序中,其中包含在应用程序清单中指定的上下文路径"myapplication",我们的插件文件夹名为"myplugin",结果是:

  
  {
      "name": "Hello world plugin testing",
      "description": "Simple hello world plugin.",
      "imports": [
      "core/c8yBranding",
      "myapplication/myplugin"
      ]
    }
            

在我们将plugin文件夹添加到我们的应用程序后,我们可以开始实现该功能。

实现插件的初始化函数

即使此示例的范围非常小,我们还是建议使用模块化方法。 因此,为该模块创建一个文件"hello.module.js",为"hello"文件夹中的控制器创建一个文件"hello.config.js"和一个文件"hello.controller.js"。

在"hello.module.js"文件中,我们初始化了我们插件的模块:


  (function () {
    'use strict';

    angular.module('myapp.hello', []);
  }());
            

在我们的"hello.config.js"文件中,我们必须配置我们的插件,以便它添加一个菜单项到导航器,并重定向到我们的视图,当点击这个菜单项。 为此,我们可以使用由QuarkIoE JavaScript API提供的服务"c8yNavigatorProvider"和"c8yViewsProvider"。 只需将服务注入到您的配置并调用以下函数:


  (function () {
    'use strict';

    angular
    .module('myapp.hello')
    .config(configure);

    configure.$inject = [
    'c8yNavigatorProvider',
    'c8yViewsProvider'
    ];

    function configure(
    c8yNavigatorProvider,
    c8yViewsProvider
    ) {
    c8yNavigatorProvider.addNavigation({ // adds a menu item to the navigator with ...
    name: 'hello', // ... the name *"hello"*
    icon: 'cube', // ... the cube icon (icons are provided by the great Font Awesome library and you can use any of their [icon names](http://fontawesome.io/icons/) without the *fa-* prefix here
    priority: 100000, // ... a priority of 100000, which means that all menu items with a priority lower than 100000 appear before this menu item and all with a priority higher than 100000 appear after this menu item
    path: 'hello' // ... */hello* as path
  });

    c8yViewsProvider.when('/hello', { // when the path "/hello" is accessed ...
    templateUrl: ':::PLUGIN_PATH:::/views/hello.html', //  ... display our html file "hello.html" inside the "views" folder of our plugin (the plugin's folder is represented using the magic string ```:::PLUGIN_PATH:::```, which is replaced by the actual path during the build process)
    controller: 'HelloController', // ... use "HelloController" as controller
    controllerAs: 'vm'
      });
    }
  }());
              
实现控制器

第二,我们必须实现我们的视图的控制器。 对于这个例子,控制器只是定义了一个变量"text",它包含简单的静态文本"hello, world":


  (function () {
    'use strict';

    angular
    .module('myapp.hello')
    .controller('HelloController', HelloController);

    function HelloController() {
    var vm = this;

    vm.text = 'hello, world';
  }
  }());
              

现在我们已经将模块,config和controller添加到我们的插件,我们必须指定"myapp.hello"作为我们的模块,并将每个javascript文件添加到我们的插件清单:


  {
    "name": "Hello world plugin testing",
    "description": "Simple hello world plugin.",
    "ngModules": [
    "myapp.hello"
    ],
    "js": [
    "hello.module.js",
    "hello.config.js",
    "hello.controller.js"
    ]
  }
              
查看模板

在我们定义了变量"text"之后,我们可以在视图模板中访问它。 要渲染文本,请将以下内容添加到hello.html文件中:


  <div>{{vm.text}}</div>
              
测试您的应用程序

要测试你的应用程序,用租户的完整url作为参数运行命令c8y server

构建和部署应用程序和插件

如果你运行`c8y --help,你将列出所有可用的命令。 您可以选择构建应用程序或插件,生成一个zip文件,您可以在任何QuarkIoE"系统管理"应用程序中手动添加,或者您可以将应用程序直接部署到您的租户。

build:app

将应用程序构建到指定的文件夹(默认为./build)。 在outputFolder中,你会发现一个名为[appContextPath]的目录和一个zip文件[appContextPath] .zip。 然后,可以在"管理"应用程序中上传此zip文件。 如果省略appContextPath,将从执行命令的路径上的"cumulocity.json"文件读取contextPath。


  $ c8y build:app [appContextPath] [outputFolder]
              
build:plugin

构建指定文件夹的插件(默认为./build)。 在outputFolder中,你会发现一个名为[pluginName]的目录和一个zip文件[pluginName].zip。 此zip文件可以在"系统管理"界面中上传,并添加到任何应用程序。


  $ c8y build:plugin <pluginName> [outputFolder]
              
deploy:app

构建所有插件,组合应用程序并将其上传到定义的租户。 如果应用程序在远程实例上不存在,它将被自动创建。 如果省略appContextPath,将从执行命令的路径上的"cumulocity.json"读取contextPath。


  $ c8y deploy:app [appContextPath]
              

插件的构建过程包括以下步骤:

  1. $inject注释angular函数。(使用ng-annotate)。
  2. 用适当的字符串替换::: PLUGIN_PATH :::
  3. 通过$templateCache转换要包括的每个html文件。
  4. 连接并缩小清单中所有定义的js文件(使用UglifyJS 2)。
  5. 编译所有less文件。
  6. 连接和缩小所有的css和less文件的结果。
  7. 复制清单'copy'中定义的所有文件。
  8. 复制插件locales文件夹内可能有的所有本地化文件。
  9. 复制插件清单。
  10. 使用上述内容创建zip文件。

应用程序的构建过程包括以下步骤:

  1. 复制导入列表中定义的每个插件的构建版本。
  2. 组合每个插件中提供的所有本地化文件,为每种语言组合为单个.json和.po文件。
  3. 生成一个index.html。
  4. 复制应用程序清单。
  5. 使用上述内容创建zip文件。
部署插件到核心应用程序

您还可以通过指定目标.json文件,在核心应用程序中添加或替换插件。 此文件的名称或路径不受限制。


  {
      "name": "Examples",
      "comment": "Release with additional example plugins",
      "applications": [
      {
      "contextPath": "administration",
      "addImports": [ "myapplication/myplugin" ]
    }
    ]
  }
              

上面的示例显示了如何将自己开发的插件添加到核心应用程序之一,在本例中为"系统管理"应用程序。 当指定插件时,请确保包含插件所在应用程序的contextPath。在这种情况下,插件"myplugin"位于具有contextPath "myapplication"的应用程序的plugins文件夹中。

如果未部署到管理租户,则需要将以下片段包含到目标.json文件中:

  
    "allApplications": {
    "availability": "PRIVATE"
    }
              

要部署目标文件,必须在部署应用程序时添加选项-t pathToTargetFile/target.json。 假设我们有以下文件夹结构:


    <<根文件夹>>
    ├── targets
    |        └── target.json
    ├── plugins
    |        └── ...
    ├── cumulocity.js
    └── package.json
              

我们必须执行以下命令:


  c8y deploy:app myapplication -t targets/target.json