Overview
This Guidance provides only 1 device state - ENABLED state by default. Customers can design multiple device states for the purpose of managing different levels of device permissions (E.g create “DISABLED” device state where a device has the permission to connect to IoT but doesn’t have permission to stream). This implementation guide demonstrates how to use AWS IoT Static Thing Group from AWS IoT Core to create additional device states and to change device state for a device using IoT Thing Group APIs. IoT Thing Group has the option to be associated with IoT policies. When a different set of permission is needed, create a new IoT Thing Group to represent the device state and attach the desired IoT policies to the thing group to achieve the desired permission control.
Note, using IoT Thing Group to manage permissions is just one of the many features of IoT Thing Group. IoT Thing Group can be used to group devices for scenarios that don’t involve permissions.
Assumptions
This implementation guide assumes the device is already in ENABLED state. If the device belongs to SpecialGroup_EnabledState
, the device is in ENABLED state. When the device has been successfully created with API StartCreateDevice
, the device is added to SpecialGroup_EnabledState
and the device inherits all the policies attached to SpecialGroup_EnabledState
.
Pre-requisites
Create a new IoT Thing Group, IoT Policies, and attach the policies to the group. See enabledStateIotPolicy
and attachEnabledPolicy
from deployment/device-management-cdk/VideoAnalyticsDeviceManagementCDK/lib/stacks/bootstrapStack/bootstrapStack.ts for an example of using CDK to create these resources. Alternatively, use AWS console to manually create these resources. For the purpose of this implementation guide, SpecialGroup_DisabledState
was created for demonstration purpose.
To differentiate thing groups for device state from thing groups for other purpose, prefix thing groups for device state with SpecialGroup_
.
Instructions to run and verify the capability
Run
Execute the Java code below to move a device from SpecialGroup_EnabledState
to the IoT Thing Group created in pre-requisite.
import software.amazon.awssdk.services.iot.IotClient;
import software.amazon.awssdk.services.iot.model.*;
import software.amazon.awssdk.services.iotdataplane.IotDataPlaneClient;
import software.amazon.awssdk.services.iotdataplane.model.IotDataPlaneException;
import software.amazon.awssdk.services.iotdataplane.model.UpdateThingShadowRequest;
import java.util.Collections;
import java.util.Map;
public void updateDeviceState(
IotClient iotClient,
final String deviceId,
final String newSpecialGroupId,
final String oldSpecialGroupId
) {
// Note, it's recommended to add device to the new device state group prior to removing device from the current device state group. That way, it's guaranteed the device doesn't loose permission during its transition from one state to another.
System.out.println("Adding device to new device state thing group" + newSpecialGroupId);
// Add device to new device state thing group
AddThingToThingGroupRequest addThingToThingGroupRequest = AddThingToThingGroupRequest
.builder()
.thingName(deviceId)
.thingGroupName(newSpecialGroupId)
.build();
iotClient.addThingToThingGroup(addThingToThingGroupRequest);
System.out.println("Removing device from current state thing group" + oldSpecialGroupId);
// Remove device from current device state thing group
RemoveThingFromThingGroupRequest removeThingToThingGroupRequest = RemoveThingFromThingGroupRequest
.builder()
.thingName(deviceId)
.thingGroupName(oldSpecialGroupId)
.build();
iotClient.removeThingFromThingGroup(removeThingToThingGroupRequest);
// Update device state in shadow so the device state is reflected when calling GetDevice
String shadowName = "provision";
// Mapping from special thing group id to device state
Map<String, String> specialGroupToDeviceState = ImmutableMap.of(
"SpecialGroup_EnabledState", "enabled",
"SpecialGroup_DisabledState","disabled"
);
// Create shadow desired state
JsonObject stateUpdate = new JsonObject();
stateUpdate.addProperty(specialGroupToDeviceState.get(newSpecialGroupId), true);
stateUpdate.add(specialGroupToDeviceState.get(oldSpecialGroupId), new JsonNull());
JsonObject desired = new JsonObject();
desired.add("desired", stateUpdate);
// Create shadow state document
JsonObject messagePayload = new JsonObject();
messagePayload.add("state", desired);
System.out.println("Updating IoT Device Shadow with new device state:" + specialGroupToDeviceState.get(newSpecialGroupId));
UpdateThingShadowRequest updateThingShadowRequest = UpdateThingShadowRequest.builder()
.thingName(deviceId)
.shadowName(shadowName)
.payload(SdkBytes.fromUtf8String(messagePayload.toString()))
.build();
try {
iotDataPlaneClient.updateThingShadow(updateThingShadowRequest);
} catch (IotDataPlaneException e) {
System.out.println(e);
}
}
Verify
After Java code is executed succesfully, sign in to the AWS IoT console. In the menu bar on the left under Manage, find All devices > Thing. Search the Thing with the device’s name. Go to Thing groups tab, and confirm the devic belongs to SpecialGroup_DisabledState
created in pre-requisite and have been removed from SpecialGroup_EnabledState
.

- Screenshot: Thing in new thing group *