fix(devices): zero out unassigned bell outputs when saving Bell Mechanisms
relay.set_config is a partial update on the firmware side — any bell index not present in the durations/outputs maps is left completely untouched. EditBellOutputsModal and OnboardDevice's bell config step both only sent entries for the currently-active bell count, so deselecting a bell (lowering the active count) never actually deactivated its output on the device — it stayed wired to whatever it was last set to. The only way to disable a bell was to reselect it and explicitly set it to "Disabled", which isn't obvious. Both now send all maxOutputs slots on every save, forcing output to 0 for anything beyond the active count, so lowering the active bell count reaches the firmware the way it visually appears to in the UI. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -51,11 +51,19 @@ export default function EditBellOutputsModal({ open, onClose, onSaved, attr, sub
|
||||
// Push to the device first — relay.set_config takes both maps in one call.
|
||||
// Only write to Firestore once the device confirms it actually applied
|
||||
// and persisted the change (sendMqttCommand's toast reports the outcome).
|
||||
//
|
||||
// relay.set_config is a partial update — any bell index NOT present in
|
||||
// these maps is left untouched by the firmware. So every slot beyond
|
||||
// activeBells must be sent explicitly as output 0 (disabled), or a bell
|
||||
// that was previously active stays wired to its old output forever,
|
||||
// even though it's no longer shown as active here. The only way to
|
||||
// deactivate a bell today is to select it and set it to Disabled — this
|
||||
// makes "deselect it" do the same thing implicitly.
|
||||
const durations = {}
|
||||
const outputs = {}
|
||||
activeRows.forEach((r, i) => {
|
||||
rows.forEach((r, i) => {
|
||||
durations[i] = r.timing
|
||||
outputs[i] = r.output
|
||||
outputs[i] = i < activeBells ? r.output : 0
|
||||
})
|
||||
await sendMqttCommand('relay.set_config', { durations, outputs })
|
||||
|
||||
|
||||
@@ -1275,9 +1275,13 @@ function ConfigureStep({ device, onDeviceUpdated, onNext, onBack }) {
|
||||
// ── Build the command sequence + Firestore patch for each group ─────────
|
||||
const buildGroups = useCallback(() => {
|
||||
const activeBellRows = bell.rows.slice(0, bell.activeBells)
|
||||
// relay.set_config is a partial update — any bell index NOT present in
|
||||
// these maps is left untouched by the firmware. Send every row (not just
|
||||
// the active ones) so anything beyond activeBells is explicitly zeroed —
|
||||
// same fix as EditBellOutputsModal.
|
||||
const durations = {}
|
||||
const outputs = {}
|
||||
activeBellRows.forEach((r, i) => { durations[i] = r.timing; outputs[i] = r.output })
|
||||
bell.rows.forEach((r, i) => { durations[i] = r.timing; outputs[i] = i < bell.activeBells ? r.output : 0 })
|
||||
|
||||
return [
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user