Group Store
GroupStore is the hierarchy and sharing manager. It stores homes, groups, subgroups, node membership, and group sharing requests.
What it does
Devices are organized into groups (homes, rooms, zones). The store tracks:
- Group hierarchy — homes, groups, and nested subgroups
- Membership — which devices belong to which group
- Sharing — who you've shared groups with and requests you've received
- Home selection — which group is currently active
API reference
Properties
| Property | Type | Purpose |
|---|---|---|
groupsList | ESPCDFGroup[] | All groups (computed from groupsByIdMap) |
groupsByIdMap | Record<string, ESPCDFGroup> | Observable map for fast O(1) lookup |
currentHomeId | string | null | ID of the currently selected home group |
issuedGroupSharingRequestsList | ESPCDFGroupSharingRequest[] | Sharing requests you've sent |
receivedGroupSharingRequestsList | ESPCDFGroupSharingRequest[] | Sharing requests you've received |
issuedGroupSharingRequests | Record<string, ESPCDFGroupSharingRequest[]> | Your requests keyed by status (pending, accepted, etc.) |
receivedGroupSharingRequests | Record<string, ESPCDFGroupSharingRequest[]> | Received requests keyed by status |
Getting the store
import { initCDF } from "@espressif/rainmaker-base-cdf";
const espCDF = await initCDF({ sdkAdaptorRegistry });
const { groupStore } = espCDF;
How to use it
Query groups
// All groups
const groups = espCDF.groupStore.groupsList;
// Single group by ID
const group = espCDF.groupStore.getGroupById("group-id");
// Currently selected home
const home = espCDF.getCurrentHome();
// Nodes belonging to the current home
const homeNodes = espCDF.getNodesForCurrentHome();
Load groups and nodes
Groups are populated via the user entity's getGroups method, then nodes are fetched per-group:
const user = espCDF.userStore.user!;
// Populates GroupStore — UserStoreSynchronizer calls groupStore.processGetGroupsRes() on getGroups success
await user.getGroups();
// Fetch nodes for a specific group — populates NodeStore
const group = espCDF.groupStore.groupsList[0]!;
await group.getNodes();
Manage group membership
const group = espCDF.groupStore.getGroupById("group-id")!;
// Fetch the group's nodes (also updates NodeStore)
await group.getNodes();
// Add / remove nodes
await group.addNodes(["node-1", "node-2"]);
await group.removeNodes(["node-1"]);
Update group info and metadata
await group.updateGroupInfo({
groupName: "Living Room",
description: "Main living area devices",
customData: { floor: 1 },
});
await group.updateMetadata({ lastModifiedBy: "user@example.com" });
Manage subgroups
// Fetch subgroups
const subs = await group.getSubGroups();
// Create a subgroup
const subGroup = await group.createSubGroup({
name: "Lights",
nodeIds: ["node-1"],
});
Share groups
// Share a group with another user
await group.share({ username: "other@example.com", role: "secondary" });
// Remove sharing
await group.removeSharingFor("other@example.com");
// Transfer ownership
await group.transfer({ username: "new-owner@example.com" });
// Get current sharing info
const { data: sharingInfo } = await group.getSharingInfo({});
Leave or delete a group
await group.leave(); // user is a secondary member
await group.delete(); // user is the primary owner
Scenes, schedules, and automations via group
Groups are the entry point for scene, schedule, and automation operations:
// Scenes
const scenes = await group.getScenes();
const scene = await group.createScene({ id: "sc-1", name: "Movie Night", nodes: [...], actions: [...] });
// Schedules
const schedules = await group.getSchedules();
const schedule = await group.createSchedule({ id: "sch-1", name: "Morning", triggers: [...], action: {...} });
// Automations
const { data: automations } = await group.getAutomations();
const automation = await group.createAutomation({ name: "Sunset lights", eventType: "daylight", ... });
GroupStoreSynchronizer routes these results into SceneStore, ScheduleStore, and AutomationStore automatically.
Manage sharing requests
// Fetch issued sharing requests
await espCDF.userStore.user!.getIssuedGroupSharingRequests();
// Fetch received sharing requests
await espCDF.userStore.user!.getReceivedGroupSharingRequests();
// Access in store (keyed by status: "pending", "accepted", "rejected", …)
const pending = espCDF.groupStore.issuedGroupSharingRequests["pending"] ?? [];
const received = espCDF.groupStore.receivedGroupSharingRequests["pending"] ?? [];
// Act on a received request
await received[0]?.accept();
await received[0]?.decline();
// Retract an issued request
await pending[0]?.remove();
Manage home selection
// Sync home (populates GroupStore and selects the primary home)
await espCDF.userStore.user?.syncHomeWithNodes();
// Switch to a different home
await espCDF.userStore.user?.setCurrentHome(home);
// Current home
const home = espCDF.getCurrentHome();
const nodes = espCDF.getNodesForCurrentHome();
Reactive group list rendering
import { observer } from "mobx-react-lite";
import type { ESPCDF } from "@espressif/rainmaker-base-cdf";
const GroupListScreen = observer(function GroupListScreen({
espCDF,
}: {
espCDF: ESPCDF;
}) {
const { groupStore } = espCDF;
return (
<FlatList
data={groupStore.groupsList}
keyExtractor={(g) => g.id}
renderItem={({ item }) => (
<Text>{item.name} ({item.nodeIds.length} nodes)</Text>
)}
/>
);
});
Handle pagination
For large group lists, groups are paginated:
const state = espCDF.groupStore.sdkAdaptorGroupsPaginationMap["rainmaker-base-sdk"];
if (state?.hasNext) {
await espCDF.groupStore.fetchNextPageGroupsForSDK("rainmaker-base-sdk");
}
See also
Implementation
API Reference