Skip to content

Comments

feat: add bulk editing support#440

Draft
deviantintegral wants to merge 13 commits intoNerivec:mainfrom
deviantintegral:add-bulk-edit
Draft

feat: add bulk editing support#440
deviantintegral wants to merge 13 commits intoNerivec:mainfrom
deviantintegral:add-bulk-edit

Conversation

@deviantintegral
Copy link

I recently installed ~20 Philips Hue Downlights and 10 Inovelli switches to control them. There were many settings I wanted to make sure were the same for each device, such as power-on behaviour and LED behaviour for the switches.

At first I was just going to hack up a script to do this over mqtt directly, but I realized this was a good opportunity to see if I AI could implement this well.

Here's the flow:

  1. Select one or more devices on the device list.
  2. The app filters through all exposes definitions that have the same name and data type. This means you can bulk edit attributes on devices even if they are of different manufacturers or models.
  3. The list shows if the values are currently the same across all of the selected devices or not - great for double-checking power on behaviour.

The new checkboxes:

SCR-20260220-rbua
SCR-20260220-rcaz

The top of the bulk settings page:

SCR-20260220-rcfn

These settings aren't in sync:

SCR-20260220-rcrt

And then, correcting them, where we get a log showing how many calls were made:

SCR-20260220-rcty

Before I do anything more (as this totally solved my immediate needs!), is this a feature you'd be interested in accepting?

Implementation Notes

My colleague has been working on a tool for AI-assisted development that I used as a part of this. It totally worked! I only spent about 10 minutes going through it's definition loop and it took about 30 to execute. I only made some minor changes after. In the interest of transparency, I have those files in this branch.

If you want to look at the PR contents at this stage, I'd suggest:

  • .ai/task-manager/archive/01--bulk-device-settings/plan-01--bulk-device-settings.md - the plan I iterated on to create this.
  • The new functions in src/utils.ts - are the assumptions around determining what can be shown as exposed features correct?

Otherwise, I've only done a very cursory review of the code, so feel free to kick it back to me if you're open to the feature in general. I'm also glad to rebase it with none of the .ai directory too. Thanks!

deviantintegral and others added 13 commits January 31, 2026 21:07
Add bulk selection state management to Zustand store with setBulkSelectedDevices
and clearBulkSelectedDevices actions, supporting multi-instance sourceIdx pattern.

Implement computeCommonExposes utility to find compatible expose features across
multiple devices, matching by name, type, and value constraints. Only includes
features with SET access. Handles nested expose structures.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add row selection with checkboxes to DevicesPage using TanStack Table's
rowSelection feature. Shows contextual toolbar with device count and
"Bulk Settings" button when 2+ devices from same source are selected.

Create BulkSettingsPage at /bulk-settings/:sourceIdx that displays common
expose features across selected devices. Shows value status indicators
(uniform/mixed/unknown) for each feature. Redirects to devices page if
selection is invalid.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add applyBulkSetting function using Promise.allSettled to send setting
changes to all selected devices in parallel. Shows loading spinner during
operation and displays toast notifications with success/failure counts.

Add expandable feature controls using daisyUI collapse component. Each
feature row shows current value status and can be expanded to modify the
setting. Changes are applied to all devices using the {ieee_address}/set
WebSocket endpoint.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add right padding to collapse-title to make room for the daisyUI
collapse arrow, preventing it from overlapping with the feature
type indicator.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add a toggle in the Common Features header that allows sorting features
by their value status (uniform → mixed → unknown) while preserving the
original order within each status group. Default is the original order.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fix corruption when toggling sort by using feature.property instead of
feature.name as the key. feature.name is not unique across features from
different paths (e.g., light.state and switch.state both have name "state"),
causing the featureValueStatuses Map to overwrite entries and React to
incorrectly reconcile components when sorting.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add aria-label attributes to status indicator icons for screen readers:
- "same value" for uniform status
- "mixed values" for mixed status
- "unknown values" for unknown status

Move the legend from a separate card at the bottom to be inline below
the "click to edit" instructional text. Mark legend icons as aria-hidden
since they are decorative (the text explains their meaning).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace the sort-by-status toggle with filter checkboxes for each status
type (uniform, mixed, unknown). Users can now show/hide features based
on their value status across devices.

The legend items are now interactive checkboxes that control filtering.
Badge shows filtered count vs total count.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@Nerivec
Copy link
Owner

Nerivec commented Feb 21, 2026

Interesting! I'm sure some would like to see this.

I only glanced at the main code, so, preliminary observations:

  • I think a modal is better suited than a page, that eliminates the need for storing more stuff in the zustand store as well. The modal package used is "no cost unless shown", so should not affect performance.
  • For the common features, I did something on this for groups recently, checks are different, but might be able to re-use some of the logic (see https://github.com/Nerivec/zigbee2mqtt-windfront/pull/405/changes).
  • Did you check that this works for composite? I see stuff being flatten, if the hierarchy is lost, it won't use proper payloads in commands.
  • I see a lot of loops, could be a performance problem for large network / multi-instance (could be looking at 100+ device selection based on networks I've seen that use few device models). Same problem for the Zigbee network, would need some kind of throttling otherwise it's a guaranteed crash on a lot of setups (this would be similar to HA Group, so same issues).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants