

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 静态事物组
<a name="thing-groups"></a>

通过将事物分类成组，您能够使用静态事物组同时管理几个事物。静态事物组包含使用控制台、CLI 或 API 管理的一组事物。另一方面，[动态事物组](dynamic-thing-groups.md)包含与指定查询匹配的事物。静态事物组还可以包含其它静态组 - 您可以构建组的层次结构。您可以将策略附加到某个父组，该策略将由其所有子组和该组及其子组中的所有事物继承。这使得控制大量事物的权限非常简单。

**注意**  
事物组策略不允许访问 AWS IoT Greengrass 数据平面操作。要允许事物访问 AWS IoT Greengrass 数据平面操作，请将权限添加到附加到事物证书的 AWS IoT 策略中。有关更多信息，请参阅*《AWS IoT Greengrass 开发人员指南》*中的[开发人员身份验证和授权](https://docs.aws.amazon.com/greengrass/v2/developerguide/device-auth#iot-policies.html)。

下面是您可以对静态事物组执行的操作：
+ 创建、描述或删除组。
+ 将事物添加到一个或多个组。
+ 从组中删除事物。
+ 列出您已创建的组。
+ 列出组的所有子组（其直接和间接后代）。
+ 列出组中的事物，包括其子组中的所有事物。
+ 列出组的所有原级组（其直接和间接父级）。
+ 添加、删除或更新组的属性。(属性是您可用于存储与组相关的信息的名称/值对。)
+ 从组中附加或分离策略。
+ 列出附加到组的策略。
+ 列出由某个事物继承的策略（借助附加到其组或其父组之一的策略）。
+ 为组中的事物配置日志记录选项。请参阅[配置 AWS IoT 日志](configure-logging.md)。
+ 创建将发送到某个组及其子组中的所有事物并在这些事物上执行的任务。请参阅[AWS IoT 职位](iot-jobs.md)。

**注意**  
将事物附加到 AWS IoT Core 策略所关联的静态事物组时，事物名称必须与客户端 ID 相匹配。

下面是静态事物组的一些限制：
+ 一个组最多可以有一个直接父级。
+ 如果一个组是另一个组的子组，则请在创建该子组时指定这一关系。
+ 以后无法更改组的父组；因此，务必先规划组的层次结构并创建父组，然后再创建父组中将包含的任何子组。
+ 

  一个事物可以属于的组数[受到限制](https://docs.aws.amazon.com//general/latest/gr/iot_device_management.html#thing-limits)。
+ 您无法将事物添加到相同层次结构的多个组中。（换言之，您无法将事物添加到父级相同的两个组中。）
+ 您无法重命名组。
+ 事物组名称不能包含国际字符，如 û、é 和 ñ。
+ 请勿在事物组名称中使用个人身份信息。事物组名称可以出现在未加密的通信和报告中。

在组上附加和分离策略能够以多种非常有效的方式增强 AWS IoT 操作的安全性。针对各个设备将策略附加到证书，然后附加到事物的方法非常费时，并且难于在整个设备实例集中快速更新或更改策略。在需要轮换某个事物上的证书时，将策略附加到事物的组可以节省步骤。并且，在更改组成员资格时，策略会动态应用到事物，因此您无需在每次组中设备成员资格更改时重新创建复杂的权限集。

## 创建静态事物组
<a name="create-thing-group"></a>

使用 **CreateThingGroup** 命令创建静态事物组：

```
$ aws iot create-thing-group --thing-group-name LightBulbs
```

**CreateThingGroup** 命令返回包含静态事物组名称、其 ID 和 ARN 的响应：

```
{
    "thingGroupName": "LightBulbs", 
    "thingGroupId": "abcdefgh12345678ijklmnop12345678qrstuvwx",
    "thingGroupArn": "arn:aws:iot:us-west-2:123456789012:thinggroup/LightBulbs"
}
```

**注意**  
我们建议不要在您的事物组名称中使用个人身份信息。

以下示例在创建静态事物组时指定其父级：

```
$ aws iot create-thing-group --thing-group-name RedLights --parent-group-name LightBulbs
```

和之前一样，**CreateThingGroup** 命令返回包含静态事物组名称、其 ID 和 ARN 的响应：

```
{
    "thingGroupName": "RedLights", 
    "thingGroupId": "abcdefgh12345678ijklmnop12345678qrstuvwx",
    "thingGroupArn": "arn:aws:iot:us-west-2:123456789012:thinggroup/RedLights",
}
```

**重要**  
创建事物组层次结构时，请注意以下限制：  
一个事物组只可以有一个直接父级。
事物组可以拥有的直接子组数量[受到限制](https://docs.aws.amazon.com//general/latest/gr/iot_device_management.html#thing-group-limits)。
组层次结构的最大深度[受到限制](https://docs.aws.amazon.com//general/latest/gr/iot_device_management.html#thing-group-limits)。
事物组可以拥有的属性数量[受到限制](https://docs.aws.amazon.com//general/latest/gr/iot_device_management.html#thing-group-limits)。(属性是您可用于存储与组相关的信息的名称/值对。) 每个属性名称和每个值的长度也[受到限制](https://docs.aws.amazon.com//general/latest/gr/iot_device_management.html#thing-group-limits)。

## 描述事物组
<a name="describe-thing-group"></a>

您可以使用 **DescribeThingGroup** 命令获取某事物组的相关信息：

```
$ aws iot describe-thing-group --thing-group-name RedLights
```

**DescribeThingGroup** 命令返回有关指定组的信息：

```
{
    "thingGroupName": "RedLights", 
    "thingGroupArn": "arn:aws:iot:us-west-2:123456789012:thinggroup/RedLights",
    "thingGroupId": "12345678abcdefgh12345678ijklmnop12345678",
    "version": 1,
    "thingGroupMetadata": {
        "creationDate": 1478299948.882
        "parentGroupName": "Lights",
        "rootToParentThingGroups": [
            {
                "groupArn": "arn:aws:iot:us-west-2:123456789012:thinggroup/ShinyObjects",
                "groupName": "ShinyObjects"
            },
            {
                "groupArn": "arn:aws:iot:us-west-2:123456789012:thinggroup/LightBulbs",
                "groupName": "LightBulbs"
            }
        ]
    },
    "thingGroupProperties": {
        "attributePayload": {
            "attributes": {
                "brightness": "3400_lumens"
            },
        },
        "thingGroupDescription": "string"
    },
}
```

## 将事物添加到静态事物组
<a name="add-thing-to-group"></a>

您可以使用 **AddThingToThingGroup** 命令将事物添加到静态事物组：

```
$ aws iot add-thing-to-thing-group --thing-name MyLightBulb --thing-group-name RedLights
```

**AddThingToThingGroup** 命令不会生成任何输出。

**重要**  
您可以将事物添加到最多 10 个组。但是，您无法将事物添加到相同层次结构的多个组中。（换而言之，您无法将事物添加到共享相同父级的两个组中。）  
如果一个事物属于尽可能多的事物组，并且其中一个或多个组是动态事物组，则可以使用 [https://docs.aws.amazon.com/iot/latest/apireference/API_AddThingToThingGroup.html#iot-AddThingToThingGroup-request-overrideDynamicGroups](https://docs.aws.amazon.com/iot/latest/apireference/API_AddThingToThingGroup.html#iot-AddThingToThingGroup-request-overrideDynamicGroups) 标志使静态组优先于动态组。

## 从静态事物组中删除事物
<a name="remove-thing-from-group"></a>

您可以使用 **RemoveThingFromThingGroup** 命令从组中删除事物：

```
$ aws iot remove-thing-from-thing-group --thing-name MyLightBulb --thing-group-name RedLights
```

**RemoveThingFromThingGroup** 命令不会生成任何输出。

## 列出事物组中的事物
<a name="list-things-in-thing-group"></a>

您可以使用 **ListThingsInThingGroup** 命令列出属于某个组的事物：

```
$ aws iot list-things-in-thing-group --thing-group-name LightBulbs
```

**ListThingsInThingGroup** 命令返回指定组中的事物列表：

```
{
    "things":[
        "TestThingA"
    ]
}
```

使用 `--recursive` 参数，您可以列出属于某个组及其所有子组中的事物：

```
$ aws iot list-things-in-thing-group --thing-group-name LightBulbs --recursive
```

```
{
    "things":[
        "TestThingA",
        "MyLightBulb"
    ]
}
```

**注意**  
此操作具有[最终一致性](https://web.stanford.edu/class/cs345d-01/rl/eventually-consistent.pdf)。换句话说，可能不会立刻反映事物组的更改。

## 列出事物组
<a name="list-thing-groups"></a>

您可以使用 **ListThingGroups** 命令列出您账户的事物组：

```
$ aws iot list-thing-groups
```

该**ListThingGroups**命令会返回您的事物组的列表 AWS 账户：

```
{
    "thingGroups": [
        {
            "groupName": "LightBulbs", 
            "groupArn": "arn:aws:iot:us-west-2:123456789012:thinggroup/LightBulbs"
        },
        {
            "groupName": "RedLights", 
            "groupArn": "arn:aws:iot:us-west-2:123456789012:thinggroup/RedLights"
        },
        {
            "groupName": "RedLEDLights", 
            "groupArn": "arn:aws:iot:us-west-2:123456789012:thinggroup/RedLEDLights"
        },
        {
            "groupName": "RedIncandescentLights", 
            "groupArn": "arn:aws:iot:us-west-2:123456789012:thinggroup/RedIncandescentLights"
        }
        {
            "groupName": "ReplaceableObjects", 
            "groupArn": "arn:aws:iot:us-west-2:123456789012:thinggroup/ReplaceableObjects"
        }
    ]
}
```

使用可选的筛选条件列出具有指定组作为父级 (`--parent-group`) 的组，或者名称以指定前缀 (`--name-prefix-filter`) 开头的组。使用 `--recursive` 参数可以列出所有子组，而不仅仅是事物组的直接子组：

```
$ aws iot list-thing-groups --parent-group LightBulbs
```

在这种情况下，该**ListThingGroups**命令将返回在您中定义的事物组的直接子组列表 AWS 账户：

```
{
    "childGroups":[
        {
            "groupName": "RedLights", 
            "groupArn": "arn:aws:iot:us-west-2:123456789012:thinggroup/RedLights"
        }
    ]
}
```

将 `--recursive` 参数与 **ListThingGroups** 命令结合使用可以列出事物组的所有子组，而不仅仅是直接子组：

```
$ aws iot list-thing-groups --parent-group LightBulbs --recursive
```

**ListThingGroups** 命令返回事物组的所有子组的列表：

```
{
    "childGroups":[
        {
            "groupName": "RedLights", 
            "groupArn": "arn:aws:iot:us-west-2:123456789012:thinggroup/RedLights"
        },
        {
            "groupName": "RedLEDLights", 
            "groupArn": "arn:aws:iot:us-west-2:123456789012:thinggroup/RedLEDLights"
        },
        {
            "groupName": "RedIncandescentLights", 
            "groupArn": "arn:aws:iot:us-west-2:123456789012:thinggroup/RedIncandescentLights"
        }
    ]
}
```

**注意**  
此操作具有[最终一致性](https://web.stanford.edu/class/cs345d-01/rl/eventually-consistent.pdf)。换句话说，可能不会立刻反映事物组的更改。

## 列出事物的组
<a name="list-thing-groups-for-thing"></a>

您可以使用 **ListThingGroupsForThing** 命令列出事物所属的直接组：

```
$ aws iot list-thing-groups-for-thing --thing-name MyLightBulb
```

**ListThingGroupsForThing** 命令会返回此事物所属的直接事物组列表：

```
{
    "thingGroups":[
        {
            "groupName": "LightBulbs", 
            "groupArn": "arn:aws:iot:us-west-2:123456789012:thinggroup/LightBulbs"
        },
        {
            "groupName": "RedLights", 
            "groupArn": "arn:aws:iot:us-west-2:123456789012:thinggroup/RedLights"
        },
        {
            "groupName": "ReplaceableObjects", 
            "groupArn": "arn:aws:iot:us-west-2:123456789012:thinggroup/ReplaceableObjects"
        }
    ]
}
```

您也可以使用内联函数在规则引擎中访问此 API `get_registry_data()`。您可以使用此功能动态访问和利用事物注册表信息（包括属性、事物类型和群组成员资格），方法是`ListThingGroupsForThing` APIs 直接在 AWS IoT 规则内调用`DescribeThing`，从而根据您的设备注册表数据进行实时消息处理和路由。有关更多信息，请参阅 [https://docs.aws.amazon.com//iot/latest/developerguide/iot-sql-functions.html#iot-sql-function-get-registry_data](https://docs.aws.amazon.com//iot/latest/developerguide/iot-sql-functions.html#iot-sql-function-get-registry_data)。

## 更新静态事物组
<a name="update-thing-group"></a>

您可以使用 **UpdateThingGroup** 命令更新静态事物组的属性：

```
$ aws iot update-thing-group --thing-group-name "LightBulbs" --thing-group-properties "thingGroupDescription=\"this is a test group\", attributePayload=\"{\"attributes\"={\"Owner\"=\"150\",\"modelNames\"=\"456\"}}"
```

**UpdateThingGroup** 命令返回一个响应，其中包含该组更新后的版本号：

```
{
    "version": 4
}
```

**注意**  
事物可以拥有的属性数量[受到限制](https://docs.aws.amazon.com//general/latest/gr/iot_device_management.html#thing-limits)。  


## 删除事物组
<a name="delete-thing-group"></a>

要删除事物组，请使用 **DeleteThingGroup** 命令：

```
$ aws iot delete-thing-group --thing-group-name "RedLights"
```

**DeleteThingGroup** 命令不会生成任何输出。

**重要**  
如果您尝试删除具有子事物组的事物组，则会收到错误：  

```
A client error (InvalidRequestException) occurred when calling the DeleteThingGroup 
operation: Cannot delete thing group : RedLights when there are still child groups attached to it.
```
您必须先删除所有子组，然后才能删除该组。

您可以删除具有子事物的组，但由组中的成员资格授予事物的任何权限将不再适用。删除附加了策略的组之前，请认真检查，确保移除这些权限不会导致组中的事物无法正常运行。此外，在更新云中的记录时，显示事物所属的组的命令（例如，**ListGroupsForThing**）可能会继续显示该组。

## 将策略附加到静态事物组
<a name="group-attach-policy"></a>

您可以使用 **AttachPolicy** 命令将策略附加到静态事物组，这样可以扩展到该组中的所有事物及其所有子组中的事物：

```
$ aws iot attach-policy \
  --target "arn:aws:iot:us-west-2:123456789012:thinggroup/LightBulbs" \
  --policy-name "myLightBulbPolicy"
```

**AttachPolicy** 命令不会生成任何输出

**重要**  
您可以向组附加最多 2 个策略。

**注意**  
我们建议不要在您的策略名称中使用个人身份信息。

`--target` 参数可以是事物组 ARN（如上所示）、证书 ARN 或 Amazon Cognito Identity。有关策略、证书和身份验证的更多信息，请参阅 [身份验证](authentication.md)。

有关更多信息，请参阅 [AWS IoT Core 策略](https://docs.aws.amazon.com/iot/latest/developerguide/iot-policies.html)。

## 从静态事物组分离策略
<a name="group-detach-policy"></a>

您可以使用 **DetachPolicy** 命令从组中分离策略，这样会更进一步地从该组中的所有事物及其所有子组中的事物分离：

```
$ aws iot detach-policy --target "arn:aws:iot:us-west-2:123456789012:thinggroup/LightBulbs" --policy-name "myLightBulbPolicy"
```

**DetachPolicy** 命令不会生成任何输出。

## 列出附加到静态事物组的策略
<a name="group-list-policies"></a>

您可以使用 **ListAttachedPolicies** 命令列出附加到静态事物组的策略：

```
$ aws iot list-attached-policies --target "arn:aws:iot:us-west-2:123456789012:thinggroup/RedLights"
```

`--target` 参数可以是事物组 ARN（如上所示）、证书 ARN 或 Amazon Cognito Identity。

添加可选的 `--recursive` 参数可以包括附加到组的父组的所有策略。

**ListAttachedPolicies** 命令返回策略列表：

```
{
    "policies": [
        "MyLightBulbPolicy" 
        ...
    ]
}
```

## 列出策略的组
<a name="group-list-targets-for-policy"></a>

您可以使用 **ListTargetsForPolicy** 命令列出策略附加到的目标，包括任何组：

```
$ aws iot list-targets-for-policy --policy-name "MyLightBulbPolicy"
```

添加可选的 `--page-size number` 参数以指定为每个查询返回的最大结果数，并在后续调用上添加 `--marker string` 参数以检索下一组结果（如果有）。

**ListTargetsForPolicy** 命令返回目标的列表以及用于检索更多结果的令牌：

```
{
    "nextMarker": "string",
    "targets": [ "string" ... ]
}
```

## 获取事物的有效策略
<a name="group-get-effective-policies"></a>

您可以使用 **GetEffectivePolicies** 命令列出对事物生效的策略，包括附加到事物所属任意组的策略（不论该组是直接父组还是间接原级）：

```
$ aws iot get-effective-policies \
  --thing-name "MyLightBulb" \
  --principal "arn:aws:iot:us-east-1:123456789012:cert/a0c01f5835079de0a7514643d68ef8414ab739a1e94ee4162977b02b12842847"
```

使用 `--principal` 参数指定附加到事物的证书的 ARN。如果您使用的是 Amazon Cognito Identity 身份验证，请使用 `--cognito-identity-pool-id` 参数，并（可选）添加 `--principal` 参数来指定特定的 Amazon Cognito Identity。如果您仅指定 `--cognito-identity-pool-id`，则返回未经身份验证用户的与该身份池角色关联的策略。如果同时使用两个参数，则返回经过身份验证用户的与该身份池角色关联的策略。

`--thing-name` 参数是可选的，可用于替代 `--principal` 参数。在使用时，将返回附加到事物所属任意组的策略以及附加到这些组的任意父组（向上直至层次结构中的根组）的策略。

**GetEffectivePolicies** 命令返回策略列表：

```
{
    "effectivePolicies": [
        {
            "policyArn": "string",
            "policyDocument": "string",
            "policyName": "string"
        }
        ...
    ]
}
```

## 测试 MQTT 操作的授权
<a name="group-test-authorization"></a>

您可以使用 **TestAuthorization** 命令测试某个事物是否允许 [MQTT](https://docs.aws.amazon.com/iot/latest/developerguide/mqtt.html) 操作 (`Publish`、`Subscribe`)：

```
aws iot test-authorization \
    --principal "arn:aws:iot:us-east-1:123456789012:cert/a0c01f5835079de0a7514643d68ef8414ab739a1e94ee4162977b02b12842847" \
    --auth-infos "{\"actionType\": \"PUBLISH\", \"resources\": [ \"arn:aws:iot:us-east-1:123456789012:topic/my/topic\"]}"
```

使用 `--principal` 参数指定附加到事物的证书的 ARN。如果使用 Amazon Cognito Identity 身份验证，请指定 Cognito Identity 作为 `--principal` 并且/或者使用 `--cognito-identity-pool-id` 参数。如果您仅指定 `--cognito-identity-pool-id`，则考虑未经身份验证用户的与该身份池角色关联的策略。如果同时使用两个参数，则考虑经过身份验证用户的与该身份池角色关联的策略。

通过列出资源和操作类型的组，并且后跟 `--auth-infos` 参数，来指定一个或多个要测试的 MQTT 操作。`actionType` 字段应包含“PUBLISH”、“SUBSCRIBE”、“RECEIVE”或“CONNECT”。该`resources`字段应包含资源列表 ARNs。请参阅[AWS IoT Core 政策](iot-policies.md)了解更多信息。

您可以通过将这些参数与 `--policy-names-to-add` 参数一起指定，测试添加策略的效果。或者，您可以通过 `--policy-names-to-skip` 参数来测试移除这些策略的效果。

您可以使用可选的 `--client-id` 参数来进一步优化结果。

**TestAuthorization** 命令返回您指定的每组 `--auth-infos` 查询允许或拒绝的操作的详细信息：

```
{
    "authResults": [
        {
            "allowed": {
                "policies": [
                    {
                        "policyArn": "string",
                        "policyName": "string"
                    }
                ]
            },
            "authDecision": "string",
            "authInfo": {
                "actionType": "string",
                "resources": [ "string" ]
            },
            "denied": {
                "explicitDeny": {
                    "policies": [
                        {
                            "policyArn": "string",
                            "policyName": "string"
                        }
                    ]
                },
                "implicitDeny": {
                    "policies": [
                        {
                            "policyArn": "string",
                            "policyName": "string"
                        }
                    ]
                }
            },
            "missingContextValues": [ "string" ]
        }
    ]
}
```