教程:添加定制函数

在本教程中,您将编写定制函数并将其打包和存储在 GitHub 存储库中。 向目录注册此函数并用于计算前,在本地环境中对其进行测试。

关于本任务

注: 要完成本教程,请使用样本设备类型模板和数据。 样本设备类型不使用最新版本的设备类型,并且不支持流式数据度量。 有关更多信息,请参阅 创建批处理或流式数据度量

在本教程中,您将编写一个定制函数 MultiplyByFactor,作用是将输入项乘以因子值。 作为功能代码的一部分,定义如何表示输入和输出 Maximo® Monitor 项目的控件。 稍后,指定输入项和因子值。

使用 execute_local_test 方法来测试功能。 此方法用于测试派生自 IoT Functions 中的基本类的任何函数。 此方法会在本地为函数生成样本数据。 它将结果写入工作目录中名为 df_test_entitity_for_function_name 的文件。 如果该函数正常工作,请将其注册到 Maximo Monitor

最后,创建一个示例机器人设备类型, Maximo Monitor 并将新 MultiplyByFactor 函数应用于该设备类型。

本教程使用 Pycharm IDE 为定制函数创建 Python 包。 若您使用 Watson Studio 其他IDE或,请确保配合使用 Python 3.9.x。

另外,IoT Functions 中提供了定制函数入门模板程序包(与此教程分开提供),用于帮助您开始构建自己的定制函数。

开始之前

您可以克隆入门软件包,并将其用作本地环境内的样本包。 克隆入门软件包可便于您为自己的定制函数安装所需的包,包括 IoT Functions。 入门软件包提供了定制包所需的目录结构的示例。

  1. 在环境中安装 Python 3.9.x
  2. 安装 GIT
  3. 为 Python 安装 pip3 软件包管理器。
  4. 安装编辑器(如 Xcode)以进行代码更新。
  5. 克隆 HelloWorld 入门模板包
    1. 打开终端窗口。
    2. 为入门软件包生成新的项目文件夹。 例如,mkdir project
    3. 切换到项目目录。 例如,cd project
    4. 克隆入门软件包。 输入:git clone --branch starter_package https://github.com/ibm-watson-iot/functions.git
    5. 验证是否已将入门软件包克隆到项目目录。
    6. 切换到入门软件包中的函数目录。 输入:cd functions
    7. 输入:git status
    8. 复制工作目录路径以供将来使用。 输入 pwd 并复制路径。
    9. 打开 setup.py 文件。 setup.py 文件定义项目所需的包名和包列表。
    10. name 参数设置为 custom{your_initials}。 将 {your_initials} 变量替换为您的缩写或其他唯一值。
    11. ibm-watson-iot/functions 存储库中,验证 iotfunction 软件包是否为正确的版本。 例如,对于 ` 8.8Maximo Monitor `,该软件包必须来自 ` 8.8.XGitHub ` 分支。 请勿将 x 版本号中的 替换为其他值。 以下文本是一个示例 setup.py 文件。 名称参数设置为 customId ,并使用 分支 8.7.X
#!/usr/bin/env python 
from setuptools import setup, find_packages
setup(name='customld', version='0.0.1', packages=find_packages(),
install_requires=['iotfunctions@git+https://github.com/ibm-watson-iot/functions.git@8.7.x'])
  1. 安装 PyCharm 社区版本。
  2. 在 PyCharm 中,将环境指向您克隆的入门软件包。 单击打开,并浏览以查找所克隆的目录。
  3. 设置新的 Pycharm 虚拟环境。
    1. 转至 PyCharm > 首选项 > 项目 <your_project> > 项目解释器。
    2. 如果要设置新的虚拟环境:
    3. 单击设置图标,然后单击添加
    4. 指定项目文件夹的位置。
    5. 将基本解释器设置为 Python 3.9.x 目录。
    6. 如果您现有虚拟环境,请将项目解释器设置为 Python 3.x。
  4. 运行以下命令以将 iotfunctions 软件包安装到 Python 环境中。 确保对您的版本使用正确的分支名称。
    pip3 install git+https://github.com/ibm-watson-iot/functions.git@8.7.x --upgrade

确保始终使用最新版本的 IoT Functions。 检查每个 Python 模块的版本是否受支持 Maximo Monitor。 如果不使用受支持的准确版本,那么管道可能会中断。

步骤

请完成以下步骤来使用定制函数对样本数据应用计算。

步骤 1:定义计算

一家研发机器人手臂的公司正在引入一个新的机器人手臂,并正在测试它的性能以及现有的机器人。 在早期测试中,团队发现对于部分机器人来说,测试期间行驶的距离过高。 经过调查后,调查人员发现用于测试的工具减慢了机器人的速度,增加了行程时间。 操作管理员希望按因子值 2 对这两个值进行调整,但希望稍后能够灵活更改因子值。

分析人员指出,类似的计算可能在其他计算中有用,并通过编写 MultiplyByFactor 类来通用化该函数。

distance * factor

步骤 2:将函数打包并存储到 GitHub 中。

  1. 在 GitHub 上为克隆的入门软件包创建新的存储库。
    1. 存储库必须具有可通过 pip 安装进行访问的 URL。
    2. 最佳做法是使该存储库成为专用存储库。 可以使用个人访问令牌来访问存储库。
  2. 将文件添加到存储库以创建主分支。 例如,添加名为 test.md 的空文件,然后单击 Commit new file
  3. 在本地 PyCharm 中打开此项目以进行编辑。
  4. 验证项目是否具有以下目录结构和文件:
    functions
    |
    |__ setup.py
    |
    |__ scripts
      |
      |_ local_test_of_function.py
    |
    |__ custom
      |
      |_ functions.py
      |_  __init__.py
  5. 将模块名称 custom 更改为唯一名称(例如,customyourinitials)。 例如,customld
  6. custom<yourinitials> 中创建 multiplybyfactor<yourinitials>.py 函数模块并粘贴以下代码。 更新 <> 中的变量以匹配您的环境。 例如,如果代码位于 GitHub 中,那么可以将 PACKAGE_URL 设置为 'git+https://<XXXXXX>@github.com/github.com/jones/starter@starter_package'

    在此函数中,您实现了两种方法。 将计算添加到 execute 方法。 在 build_ui 方法中为函数设置输入和输出参数。 通过配置用户界面配置这些自变量。

    import inspect
    import logging
    import datetime as dt
    import math
    from sqlalchemy.sql.sqltypes import TIMESTAMP,VARCHAR
    import numpy as np
    import pandas as pd
    
    from iotfunctions.base import BaseTransformer
    from iotfunctions import ui
    
    logger = logging.getLogger(__name__)
    
    # Specify the URL to your package here.
    # This URL must be accessible via pip install.
    # Example assumes the repository is private.
    # Replace XXXXXX with your personal access token.
    # After @ you must specify a branch.
    
    PACKAGE_URL = 'git+https://XXXXXX@github.com/<user_id><path_to_repository>@starter_package'
    
    class MultiplyByFactor<YourInitials>(BaseTransformer):
    
        def __init__(self, input_items, factor, output_items):
    
            self.input_items = input_items
            self.output_items = output_items
            self.factor = float(factor)
            super().__init__()
        def execute(self, df):
            df = df.copy()
            for i,input_item in enumerate(self.input_items):
                df[self.output_items[i]] = df[input_item] * self.factor
            return df
    
        @classmethod
        def build_ui(cls):
            #define arguments that behave as function inputs
            inputs = []
            inputs.append(ui.UIMultiItem(
                    name = 'input_items',
                    datatype=float,
                    description = "Data items adjust",
                    output_item = 'output_items',
                    is_output_datatype_derived = True)
                          )        
            inputs.append(ui.UISingle(
                    name = 'factor',
                    datatype=float)
                          )
            outputs = []
            return (inputs,outputs)   

步骤 3:将凭证保存到文件

设置凭据以连接到 Maximo Monitor

  1. 下载credentials_as.json 文件
  2. 将变量替换为数据,然后将文件保存到本地计算机。

凭证文件用于在本地运行或测试函数。 请勿将此文件推送到步骤 4中的外部存储库。

步骤 4:将本地更改推送到 GitHub 存储库

验证是否已完成这些步骤:

  • 所修改的文件仍指向从中克隆代码的 GitHub 存储库。 将远程存储库更改为 GitHub 存储库。
  • 在将更改落实到外部目录之前,请验证凭证文件是否未随附于函数代码。

将函数代码推送到 GitHub 中的外部存储库。

  1. 在项目文件夹中打开终端窗口。
  2. 输入:git remote -v。 远程存储库仍指向 https://github.com/ibm-watson-iot/functions
  3. 使用以下命令更改远程源 URL:
    git remote set-url origin URL_To_YOUR_GITHUB_REPOSITORY
    确认访存和推送 URL 都指向您的存储库。
  4. 使用以下命令添加上游远程 URL。 输入:
    git remote add upstream https://github.com/ibm-watson-iot/functions.git
  5. 向 GIT 添加文件并落实。
    1. 在 PyCharm 中,选择 custom<your_initials> 目录。
    2. 选择“Git > 添加”。
    3. 选择“Git > 落实”。
    4. 在“落实更改”窗口中,单击落实
    5. 选择“Git > 存储库 > 推送”。
    6. 单击推送
  6. 验证模块是否已推送到存储库中的 starter_package 分支。

步骤 5:在本地环境中安装定制函数

在本地环境中安装定制函数。 更新 <> 中的变量以匹配您的环境。

pip3 install git+https://<XXXXXX>@github.com/<user_id><path_to_repository>@starter_package --upgrade

例如:

pip3 install git+https://<XXXXXX>@github.com/jones/starter@starter_package --upgrade

将 <xxxxxx> 替换为您的个人访问令牌

步骤 6:在本地测试定制函数。

  1. scripts 文件夹中创建名为 test_my_custom_function.py 的脚本。 在此脚本中,导入 Python 库和包:
    import datetime as dt
    import json
    import pandas as pd
    import numpy as np
    from sqlalchemy import Column, Integer, String, Float, DateTime, Boolean, func
    from iotfunctions.base import BaseTransformer
    from iotfunctions.metadata import EntityType
    from iotfunctions.db import Database
    from iotfunctions import ui
  2. 连接到 Maximo Monitor. 在 test_my_custom_function.py 脚本中,添加:
    with open('credentials_as.json', encoding='utf-8') as F:
      credentials = json.loads(F.read())
    db_schema = None
    db = Database(credentials=credentials)
  3. 导入并实例化函数。 在 test_my_custom_function.py 脚本中,添加以下代码。 更新 <> 中的变量以匹配您的环境。
    from custom<yourinitials>.multiplybyfactor<yourinitials> import MultiplyByFactor<YourInitials>
    fn = MultiplyByFactor<YourInitials>(
        input_items = ['speed', 'travel_time'],
        factor = '2',
        output_items = ['adjusted_speed', 'adjusted_travel_time']
                  )
    df = fn.execute_local_test(db=db, db_schema=db_schema, generate_days=1,to_csv=True)
    print(df)
  4. 从命令行运行此脚本。 日期帧结果将保存到 .csv 文件中。 在 scripts 目录中查找 df_test_entity_for_multiplybyfactor<your_initials>.csv 。 输入:
    python3 test_my_custom_function.py

步骤 7:注册定制函数。

  1. scripts 文件夹中创建名为 register_my_custom_function.py 的脚本。 在此脚本中,导入 Python 库和包:
    import datetime as dt
    import json
    import pandas as pd
    import numpy as np
    from sqlalchemy import Column, Integer, String, Float, DateTime, Boolean, func
    from iotfunctions.base import BaseTransformer
    from iotfunctions.metadata import EntityType
    from iotfunctions.db import Database
    from iotfunctions import ui
  2. 连接到 Maximo Monitor. 在 register_my_custom_function.py 脚本中,添加:
    with open('credentials_as.json', encoding='utf-8') as F:
      credentials = json.loads(F.read())
    db_schema = None
    db = Database(credentials=credentials)
    ``
  3. register_my_custom_function.py 脚本中,要注册该函数,请添加以下代码。 更新 <> 中的变量以匹配您的环境。
    from custom<yourinitials>.multiplybyfactor<yourinitials> import MultiplyByFactor<YourInitials>
    
    db.register_functions([MultiplyByFactor<YourInitials>])
  4. 从命令行运行此脚本。 例如:
    python3 register_my_custom_function.py

步骤 8:创建样本设备类型。

注意: 创建示例设备类型的步骤仅适用于 Maximo Manage 9.0 及更高版本。 在 Maximo Manage 8.9 及更早版本中,请进入设置页面的 " 设备 "选项卡,点击加号(+)图标选择机器人样本类型模板。
  1. "设置 "页面的 " 设备类型 "选项卡上,单击 "添加设备类型 +"以添加新设备类型。
  2. 选择工业机器人样本类型模板。
  3. 在设备类型名称字段中为设备类型指定一个名称。
  4. 单击 创建
  5. 从 "设备类型 "中选择新创建的样本设备类型,单击省略号按钮(3 点垂直排列)并选择 " 编辑 ",这将打开样本设备类型的 " 数据 "选项卡。

度量值最多需要 5 分钟才能生成。

步骤 9:将定制函数应用于设备类型。

  1. 如果尚未创建 distance 度量,请添加该度量。 遵循教程:添加表达式中的步骤
  2. 数据 选项卡中,单击 创建度量
  3. 从目录中选择 MultiplyByFactor<YourInitials> 函数。
  4. 设置作用域,然后单击 下一步
  5. 在“因子”字段中,输入 2。
  6. input_item 字段中,选择 distance
  7. 单击下一个
  8. 将输出重命名为 "仲裁距离"。
  9. 单击 创建
  10. 在数据项列表中,选择 adjusted_distance。 请等待最多5分钟, Maximo Monitor 以便系统根据示例数据评估自定义函数。